diff --git a/.github/workflows/CI-node.yaml b/.github/workflows/CI-node.yaml index 850af1b9f6..7b52745ce8 100644 --- a/.github/workflows/CI-node.yaml +++ b/.github/workflows/CI-node.yaml @@ -58,51 +58,3 @@ jobs: - name: Check app linting, format and typescript run: ./scripts/lint_apps.sh - - ##tests-main: - ## needs: lint-format - ## runs-on: ubuntu-latest - ## defaults: - ## run: - ## shell: bash - ## working-directory: ./backend -## - ## steps: - ## - name: Check out repository code - ## uses: actions/checkout@v2 -## - ## - name: Setup Node - ## uses: actions/setup-node@v3 - ## with: - ## node-version: 20 -## - ## - name: Install dependencies - ## run: cd .. && corepack enable && pnpm i --frozen-lockfile -## - ## - name: Run tests - ## working-directory: ./backend - ## run: SERVICE=test pnpm test -- --testPathIgnorePatterns=serverless - - ## tests-serverless: - ## needs: lint-format - ## runs-on: ubuntu-latest - ## defaults: - ## run: - ## shell: bash - ## working-directory: ./backend -## - ## steps: - ## - name: Check out repository code - ## uses: actions/checkout@v2 -## - ## - name: Setup Node - ## uses: actions/setup-node@v3 - ## with: - ## node-version: 20 -## - ## - name: Install dependencies - ## run: cd .. && corepack enable && pnpm i --frozen-lockfile -## - ## - name: Run tests - ## working-directory: ./backend - ## run: SERVICE=test pnpm test -- --testPathPattern="serverless\/" diff --git a/backend/.env.test b/backend/.env.test deleted file mode 100755 index 29aee1f910..0000000000 --- a/backend/.env.test +++ /dev/null @@ -1,16 +0,0 @@ -# DB settings -CROWD_DB_PORT=5433 - -# Redis settings -CROWD_REDIS_PORT=6380 - -# Sqs settings -CROWD_KAFKA_BROKERS=kafka:9092 - -# Temporal settings -CROWD_TEMPORAL_SERVER_URL=localhost:7234 -CROWD_TEMPORAL_ENCRYPTION_KEY_ID=test -CROWD_TEMPORAL_ENCRYPTION_KEY=dXfA98nyNcIuvW1RZecqEIREKgDMnGjF - - -PRODUCT_DB_PORT=5435 \ No newline at end of file diff --git a/backend/config/test.json b/backend/config/test.json deleted file mode 100644 index 8a2bf7cd25..0000000000 --- a/backend/config/test.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "redis": {}, - "nango": {} -} diff --git a/backend/docker-compose.test.yaml b/backend/docker-compose.test.yaml deleted file mode 100644 index 809141c53b..0000000000 --- a/backend/docker-compose.test.yaml +++ /dev/null @@ -1,79 +0,0 @@ -version: '3.1' - -services: - db-test: - image: postgres:14-alpine - environment: - POSTGRES_PASSWORD: example - POSTGRES_DB: crowd-web - ports: - - 5433:5432 - networks: - - crowd-bridge-test - - product-db-test: - image: postgres:14-alpine - environment: - POSTGRES_PASSWORD: example - POSTGRES_DB: product-db - ports: - - 5435:5432 - networks: - - crowd-bridge-test - - kafka: - image: bitnami/kafka:latest - restart: unless-stopped - environment: - - KAFKA_CFG_NODE_ID=0 - - KAFKA_CFG_PROCESS_ROLES=controller,broker - - KAFKA_CFG_LISTENERS=PLAINTEXT://0.0.0.0:9097,PLAINTEXT_HOST://0.0.0.0:9098,CONTROLLER://0.0.0.0:9099 - - KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT,CONTROLLER:PLAINTEXT - - KAFKA_CFG_CONTROLLER_QUORUM_VOTERS=0@kafka:9094 - - KAFKA_CFG_CONTROLLER_LISTENER_NAMES=CONTROLLER - - KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://kafka:9092,PLAINTEXT_HOST://127.0.0.1:9098 - - KAFKA_CFG_INTER_BROKER_LISTENER_NAME=PLAINTEXT - - KAFKA_CFG_LOG_DIRS=/opt/bitnami/kafka/data - - KAFKA_CFG_OFFSETS_TOPIC_REPLICATION_FACTOR=1 - ports: - - '9097:9092' - - '9098:9093' - - '9099:9094' - networks: - - crowd-bridge-test - - open-search-test: - image: opensearchproject/opensearch:2.7.0 - environment: - - discovery.type=single-node - - bootstrap.memory_lock=true - ulimits: - memlock: - soft: -1 - hard: -1 - ports: - - 9201:9200 - - 9601:9600 - networks: - - crowd-bridge-test - - redis-test: - image: redis - ports: - - 6380:6379 - networks: - - crowd-bridge-test - - temporal-test: - build: - context: ../scripts/scaffold/temporal - restart: always - ports: - - '7234:7233' - - '8234:8233' - networks: - - crowd-bridge-test - -networks: - crowd-bridge-test: - external: true diff --git a/backend/jest.config.js b/backend/jest.config.js deleted file mode 100644 index 6fee5b31b9..0000000000 --- a/backend/jest.config.js +++ /dev/null @@ -1,41 +0,0 @@ -/* eslint-disable @typescript-eslint/no-var-requires */ - -const tsconfig = require('./tsconfig.json') - -const fromPairs = (pairs) => pairs.reduce((res, [key, value]) => ({ ...res, [key]: value }), {}) - -/** - * tsconfig の paths の設定から moduleNameMapper を生成する - * {"@app/*": ["src/*"]} -> {"@app/(.*)": "/src/$1"} - */ -function moduleNameMapperFromTSPaths(tsconf) { - return fromPairs( - Object.entries(tsconf.compilerOptions.paths).map(([k, [v]]) => [ - k.replace(/\*/, '(.*)'), - `/${tsconf.compilerOptions.baseUrl}/${v.replace(/\*/, '$1')}`, - ]), - ) -} - -/** @type {import('ts-jest/dist/types').JestConfigWithTsJest} */ -module.exports = { - preset: 'ts-jest', - transform: { - '^.+\\.(ts|tsx)$': [ - 'ts-jest', - { - babelConfig: true, - isolatedModules: true, - }, - ], - }, - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'], - testEnvironment: 'node', - testPathIgnorePatterns: ['/dist'], - testTimeout: 90000, - testRegex: ['__tests__/.*tests?.ts$'], - bail: false, - roots: [''], - moduleNameMapper: moduleNameMapperFromTSPaths(tsconfig), - transformIgnorePatterns: ['node_modules/(?!(axios|@crowd/))/'], -} diff --git a/backend/package.json b/backend/package.json index 08967ace8a..85bd759f52 100644 --- a/backend/package.json +++ b/backend/package.json @@ -139,7 +139,6 @@ "@types/config": "^3.3.0", "@types/cron": "^2.0.0", "@types/html-to-text": "^8.1.1", - "@types/jest": "^29.5.1", "@types/node": "~18.0.4", "@types/sanitize-html": "^2.6.2", "@types/superagent": "^4.1.15", @@ -154,13 +153,11 @@ "eslint-config-airbnb-typescript": "^16.1.4", "eslint-config-prettier": "^8.5.0", "eslint-plugin-import": "^2.25.4", - "jest": "^29.5.0", "node-mocks-http": "1.9.0", "nodemon": "2.0.4", "prettier": "^3.3.3", "rdme": "^7.2.0", "supertest": "^6.2.2", - "ts-jest": "^29.1.0", "tsx": "^4.7.1", "typescript": "^5.6.3" }, diff --git a/backend/src/database/repositories/__tests__/eagleEyeActionRepository.test.ts b/backend/src/database/repositories/__tests__/eagleEyeActionRepository.test.ts deleted file mode 100644 index 91fc1ca91c..0000000000 --- a/backend/src/database/repositories/__tests__/eagleEyeActionRepository.test.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { EagleEyeAction, EagleEyeActionType, EagleEyeContent } from '@crowd/types' - -import SequelizeTestUtils from '../../utils/sequelizeTestUtils' -import EagleEyeActionRepository from '../eagleEyeActionRepository' -import EagleEyeContentRepository from '../eagleEyeContentRepository' - -const db = null - -describe('eagleEyeActionRepository tests', () => { - beforeEach(async () => { - await SequelizeTestUtils.wipeDatabase(db) - }) - - afterAll((done) => { - // Closing the DB connection allows Jest to exit successfully. - SequelizeTestUtils.closeConnection(db) - done() - }) - - describe('createActionForContent method', () => { - it('Should create a an action for a content succesfully', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - - const content = { - platform: 'reddit', - url: 'https://some-post-url', - post: { - title: 'post title', - body: 'post body', - }, - postedAt: '2020-05-27T15:13:30Z', - tenantId: mockIRepositoryOptions.currentTenant.id, - } as EagleEyeContent - - const contentCreated = await EagleEyeContentRepository.create(content, mockIRepositoryOptions) - - const action: EagleEyeAction = { - type: EagleEyeActionType.BOOKMARK, - timestamp: '2022-07-27T19:13:30Z', - } - - const actionCreated = await EagleEyeActionRepository.createActionForContent( - action, - contentCreated.id, - mockIRepositoryOptions, - ) - - actionCreated.createdAt = (actionCreated.createdAt as Date).toISOString().split('T')[0] - actionCreated.updatedAt = (actionCreated.updatedAt as Date).toISOString().split('T')[0] - - const expectedAction = { - id: actionCreated.id, - ...action, - timestamp: new Date(actionCreated.timestamp), - contentId: contentCreated.id, - actionById: mockIRepositoryOptions.currentUser.id, - tenantId: mockIRepositoryOptions.currentTenant.id, - createdAt: SequelizeTestUtils.getNowWithoutTime(), - updatedAt: SequelizeTestUtils.getNowWithoutTime(), - } - expect(expectedAction).toStrictEqual(actionCreated) - }) - }) -}) diff --git a/backend/src/database/repositories/__tests__/eagleEyeContentRepository.test.ts b/backend/src/database/repositories/__tests__/eagleEyeContentRepository.test.ts deleted file mode 100644 index 39e5a78993..0000000000 --- a/backend/src/database/repositories/__tests__/eagleEyeContentRepository.test.ts +++ /dev/null @@ -1,553 +0,0 @@ -import { EagleEyeActionType, EagleEyeContent } from '@crowd/types' - -import SequelizeTestUtils from '../../utils/sequelizeTestUtils' -import EagleEyeActionRepository from '../eagleEyeActionRepository' -import EagleEyeContentRepository from '../eagleEyeContentRepository' - -const db = null - -describe('eagleEyeContentRepository tests', () => { - beforeEach(async () => { - await SequelizeTestUtils.wipeDatabase(db) - }) - - afterAll((done) => { - // Closing the DB connection allows Jest to exit successfully. - SequelizeTestUtils.closeConnection(db) - done() - }) - - describe('create method', () => { - it('Should create a content succesfully', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - - const content = { - platform: 'reddit', - url: 'https://some-post-url', - post: { - title: 'post title', - body: 'post body', - }, - postedAt: '2020-05-27T15:13:30Z', - tenantId: mockIRepositoryOptions.currentTenant.id, - } as EagleEyeContent - - const created = await EagleEyeContentRepository.create(content, mockIRepositoryOptions) - - created.createdAt = (created.createdAt as Date).toISOString().split('T')[0] - created.updatedAt = (created.updatedAt as Date).toISOString().split('T')[0] - - const expectedCreated = { - id: created.id, - ...content, - postedAt: new Date(content.postedAt), - actions: [], - createdAt: SequelizeTestUtils.getNowWithoutTime(), - updatedAt: SequelizeTestUtils.getNowWithoutTime(), - tenantId: mockIRepositoryOptions.currentTenant.id, - } - expect(created).toStrictEqual(expectedCreated) - }) - - /* - - it('Should create a content with unix timestamp', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - - const withUnix = { - sourceId: 'sourceId', - vectorId: '123', - status: null, - platform: 'hacker_news', - title: 'title', - postAttributes: { - score: 10, - }, - userAttributes: { [PlatformType.GITHUB]: 'hey', [PlatformType.TWITTER]: 'ho' }, - text: 'text', - url: 'url', - timestamp: 1660712134, - - username: 'username', - keywords: ['keyword1', 'keyword2'], - similarityScore: 0.9, - } - - const created = await EagleEyeContentRepository.upsert(withUnix, mockIRepositoryOptions) - - created.createdAt = created.createdAt.toISOString().split('T')[0] - created.updatedAt = created.updatedAt.toISOString().split('T')[0] - - const expectedCreated = { - id: created.id, - ...toCreate, - timestamp: new Date(1660712134 * 1000), - importHash: null, - createdAt: SequelizeTestUtils.getNowWithoutTime(), - updatedAt: SequelizeTestUtils.getNowWithoutTime(), - deletedAt: null, - tenantId: mockIRepositoryOptions.currentTenant.id, - createdById: mockIRepositoryOptions.currentUser.id, - updatedById: mockIRepositoryOptions.currentUser.id, - } - expect(created).toStrictEqual(expectedCreated) - }) - - - - - }) - - describe('find by id method', () => { - it('Should find an existing record', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - const created = await EagleEyeContentRepository.upsert(toCreate, mockIRepositoryOptions) - - const id = created.id - const found = await EagleEyeContentRepository.findById(id, mockIRepositoryOptions) - expect(found.id).toBe(id) - }) - - it('Should throw 404 error when no tag found with given id', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - const { randomUUID } = require('crypto') - - await expect(() => - EagleEyeContentRepository.findById(randomUUID(), mockIRepositoryOptions), - ).rejects.toThrowError(new Error404()) - }) - }) - - describe('find and count all method', () => { - it('Should find all records without filters', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - - await addAll(mockIRepositoryOptions) - - const found = await EagleEyeContentRepository.findAndCountAll( - { filter: {} }, - mockIRepositoryOptions, - ) - expect(found.count).toBe(5) - }) - - it('Filter by date', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - - await addAll(mockIRepositoryOptions) - - const found = await EagleEyeContentRepository.findAndCountAll( - { - filter: { - timestampRange: [moment().subtract(1, 'day').toISOString()], - }, - }, - mockIRepositoryOptions, - ) - expect(found.count).toBe(3) - }) - - it('Filter by nDays', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - - await addAll(mockIRepositoryOptions) - - const found = await EagleEyeContentRepository.findAndCountAll( - { - filter: { - nDays: 1, - }, - }, - mockIRepositoryOptions, - ) - expect(found.count).toBe(3) - }) - - it('Filter by status NULL', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - - await addAll(mockIRepositoryOptions) - - const found = await EagleEyeContentRepository.findAndCountAll( - { - filter: { - status: 'NULL', - }, - }, - mockIRepositoryOptions, - ) - expect(found.count).toBe(3) - }) - - it('Filter by status NOT_NULL', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - - await addAll(mockIRepositoryOptions) - - const found = await EagleEyeContentRepository.findAndCountAll( - { - filter: { - status: 'NOT_NULL', - }, - }, - mockIRepositoryOptions, - ) - expect(found.count).toBe(2) - }) - - it('Filter by status engaged', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - - await addAll(mockIRepositoryOptions) - - const found = await EagleEyeContentRepository.findAndCountAll( - { - filter: { - status: 'engaged', - }, - }, - mockIRepositoryOptions, - ) - expect(found.count).toBe(1) - }) - - it('Filter by status rejected', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - - await addAll(mockIRepositoryOptions) - - const found = await EagleEyeContentRepository.findAndCountAll( - { - filter: { - status: 'rejected', - }, - }, - mockIRepositoryOptions, - ) - expect(found.count).toBe(1) - }) - - it('Filter by platform', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - - await addAll(mockIRepositoryOptions) - - const found = await EagleEyeContentRepository.findAndCountAll( - { - filter: { - platforms: 'hacker_news', - }, - }, - mockIRepositoryOptions, - ) - expect(found.count).toBe(2) - }) - - it('Filter by several platforms', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - - await addAll(mockIRepositoryOptions) - await new EagleEyeContentService(mockIRepositoryOptions).upsert({ - sourceId: 't1', - vectorId: 't1', - url: 'url devto 3', - username: 'devtousername3', - status: null, - platform: 'twitter', - timestamp: moment().subtract(1, 'week').toDate(), - keywords: ['keyword3', 'keyword2'], - title: 'title devto 3', - }) - - const found = await EagleEyeContentRepository.findAndCountAll( - { - filter: { - platforms: 'hacker_news,twitter', - }, - }, - mockIRepositoryOptions, - ) - expect(found.count).toBe(3) - }) - - it('Filter by timestamp and status', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - - await addAll(mockIRepositoryOptions) - - expect( - ( - await EagleEyeContentRepository.findAndCountAll( - { - filter: { - timestampRange: [moment().subtract(1, 'day').toISOString()], - status: 'NULL', - }, - }, - mockIRepositoryOptions, - ) - ).count, - ).toBe(2) - }) - - it('Filter by keywords', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - - await addAll(mockIRepositoryOptions) - - const k1 = { - sourceId: 'sourceIdk1', - vectorId: 'sourceIdk1', - status: null, - platform: 'hacker_news', - title: 'title', - userAttributes: { [PlatformType.GITHUB]: 'hey', [PlatformType.TWITTER]: 'ho' }, - text: 'text', - postAttributes: { - score: 10, - }, - url: 'url', - timestamp: new Date(), - username: 'username', - keywords: ['keyword1'], - similarityScore: 0.9, - } - - await new EagleEyeContentService(mockIRepositoryOptions).upsert(k1) - - const k2 = { - sourceId: 'sourceIdk2', - vectorId: 'sourceIdk2', - status: null, - platform: 'hacker_news', - title: 'title', - userAttributes: { [PlatformType.GITHUB]: 'hey', [PlatformType.TWITTER]: 'ho' }, - text: 'text', - postAttributes: { - score: 10, - }, - url: 'url', - timestamp: new Date(), - username: 'username', - keywords: ['keyword2'], - similarityScore: 0.9, - } - - try { - await EagleEyeContentRepository.findAndCountAll( - { - filter: { - keywords: 'keyword1,keyword2', - }, - }, - mockIRepositoryOptions, - ) - } catch (e) { - console.log(e) - } - - await new EagleEyeContentService(mockIRepositoryOptions).upsert(k2) - - expect( - ( - await EagleEyeContentRepository.findAndCountAll( - { - filter: { - keywords: 'keyword1,keyword2', - }, - }, - mockIRepositoryOptions, - ) - ).count, - ).toBe(5) - }) - }) - - describe('update method', () => { - it('Should update a record', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - - const created = await EagleEyeContentRepository.upsert(toCreate, mockIRepositoryOptions) - - const id = created.id - const updated = await EagleEyeContentRepository.update( - id, - { status: 'rejected', username: 'updated' }, - mockIRepositoryOptions, - ) - expect(updated.id).toBe(id) - expect(updated.status).toBe('rejected') - expect(updated.username).toBe('updated') - }) - - it('Should throw 404 error when no content found with given id', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - const { randomUUID } = require('crypto') - - await expect(() => - EagleEyeContentRepository.update(randomUUID(), {}, mockIRepositoryOptions), - ).rejects.toThrowError(new Error404()) - }) - - it('Should throw an error for an invalid status', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - - const created = await EagleEyeContentRepository.upsert(toCreate, mockIRepositoryOptions) - - const id = created.id - - await expect(() => - EagleEyeContentRepository.update(id, { status: 'smth' }, mockIRepositoryOptions), - ).rejects.toThrowError(new Error400('en', 'errors.invalidEagleEyeStatus.message')) - }) - - it('Keywords should not be updated', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - - const created = await EagleEyeContentRepository.upsert(toCreate, mockIRepositoryOptions) - - const id = created.id - const updated = await EagleEyeContentRepository.update( - id, - { keywords: ['1', '2'] }, - mockIRepositoryOptions, - ) - expect(updated.id).toBe(id) - expect(updated.keywords).toStrictEqual(created.keywords) - }) - }) - */ - }) - - describe('findAndCountAll method', () => { - it('Should find eagle eye contant, various cases', async () => { - // create random tenant with one user - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - - // create additional users for same tenant to test out actionBy filtering - const randomUser = await SequelizeTestUtils.getRandomUser() - - console.log('random user: ') - console.log(randomUser) - - const user2 = await mockIRepositoryOptions.database.user.create(randomUser) - - await mockIRepositoryOptions.database.tenantUser.create({ - roles: ['admin'], - status: 'active', - tenantId: mockIRepositoryOptions.currentTenant.id, - userId: user2.id, - }) - - // create few content - // one without any actions - await EagleEyeContentRepository.create( - { - platform: 'reddit', - url: 'https://some-reddit-url', - post: { - title: 'post title', - body: 'post body', - }, - postedAt: '2020-05-27T15:13:30Z', - tenantId: mockIRepositoryOptions.currentTenant.id, - }, - mockIRepositoryOptions, - ) - - // one with a bookmark action - let c2 = await EagleEyeContentRepository.create( - { - platform: 'hackernews', - url: 'https://some-hackernews-url', - post: { - title: 'post title', - body: 'post body', - }, - postedAt: '2022-06-27T19:14:44Z', - tenantId: mockIRepositoryOptions.currentTenant.id, - }, - mockIRepositoryOptions, - ) - - // add bookmark action - await EagleEyeActionRepository.createActionForContent( - { - type: EagleEyeActionType.BOOKMARK, - timestamp: '2022-07-27T19:13:30Z', - }, - c2.id, - mockIRepositoryOptions, - ) - - c2 = await EagleEyeContentRepository.findById(c2.id, mockIRepositoryOptions) - - // another content with a thumbs-up(user1) and a bookmark(user2) action - let c3 = await EagleEyeContentRepository.create( - { - platform: 'devto', - url: 'https://some-devto-url', - post: { - title: 'post title', - body: 'post body', - }, - postedAt: '2022-06-27T19:14:44Z', - tenantId: mockIRepositoryOptions.currentTenant.id, - }, - mockIRepositoryOptions, - ) - - // add the thumbs up action - await EagleEyeActionRepository.createActionForContent( - { - type: EagleEyeActionType.THUMBS_UP, - timestamp: '2022-09-30T23:11:10Z', - }, - c3.id, - mockIRepositoryOptions, - ) - - // also add bookmark from user2 - await EagleEyeActionRepository.createActionForContent( - { - type: EagleEyeActionType.BOOKMARK, - timestamp: '2022-09-30T23:11:10Z', - }, - c3.id, - { ...mockIRepositoryOptions, currentUser: user2 }, - ) - - c3 = await EagleEyeContentRepository.findById(c3.id, mockIRepositoryOptions) - - // filter by action type - let res = await EagleEyeContentRepository.findAndCountAll( - { - advancedFilter: { - action: { - type: EagleEyeActionType.BOOKMARK, - }, - }, - }, - mockIRepositoryOptions, - ) - - expect(res.count).toBe(2) - expect(res.rows.sort((a, b) => (a.createdAt > b.createdAt ? 1 : -1))).toStrictEqual([c2, c3]) - - // filter by actionBy - res = await EagleEyeContentRepository.findAndCountAll( - { - advancedFilter: { - action: { - actionById: user2.id, - }, - }, - }, - mockIRepositoryOptions, - ) - - expect(res.count).toBe(1) - expect(res.rows).toStrictEqual([c3]) - }) - }) -}) diff --git a/backend/src/database/repositories/__tests__/integrationRepository.test.ts b/backend/src/database/repositories/__tests__/integrationRepository.test.ts deleted file mode 100644 index a280cfc72b..0000000000 --- a/backend/src/database/repositories/__tests__/integrationRepository.test.ts +++ /dev/null @@ -1,109 +0,0 @@ -import { PlatformType } from '@crowd/types' - -import SequelizeTestUtils from '../../utils/sequelizeTestUtils' -import IntegrationRepository from '../integrationRepository' - -const db = null - -describe('Integration repository tests', () => { - beforeEach(async () => { - await SequelizeTestUtils.wipeDatabase(db) - }) - - afterAll((done) => { - // Closing the DB connection allows Jest to exit successfully. - SequelizeTestUtils.closeConnection(db) - done() - }) - - describe('Find all active integrations', () => { - it('Should find a single active integration', async () => { - const int1 = { - status: 'done', - platform: PlatformType.TWITTER, - } - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - await IntegrationRepository.create(int1, mockIRepositoryOptions) - - const found: any = await IntegrationRepository.findAllActive(PlatformType.TWITTER, 1, 100) - expect(found[0].tenantId).toBeDefined() - expect(found.length).toBe(1) - }) - - it('Should find all active integrations for a platform', async () => { - const int1 = { - status: 'done', - platform: PlatformType.TWITTER, - } - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - await IntegrationRepository.create(int1, mockIRepositoryOptions) - - const mockIRepositoryOptions2 = await SequelizeTestUtils.getTestIRepositoryOptions(db) - await IntegrationRepository.create(int1, mockIRepositoryOptions2) - - const found = await IntegrationRepository.findAllActive(PlatformType.TWITTER, 1, 100) - expect(found.length).toBe(2) - }) - - it('Should only find active integrations', async () => { - const int1 = { - status: 'done', - platform: PlatformType.TWITTER, - } - - const int2 = { - status: 'todo', - platform: PlatformType.TWITTER, - } - - const int3 = { - status: 'in-progress', - platform: PlatformType.TWITTER, - } - - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - await IntegrationRepository.create(int1, mockIRepositoryOptions) - - const mockIRepositoryOptions2 = await SequelizeTestUtils.getTestIRepositoryOptions(db) - await IntegrationRepository.create(int1, mockIRepositoryOptions2) - - const mockIRepositoryOptions3 = await SequelizeTestUtils.getTestIRepositoryOptions(db) - await IntegrationRepository.create(int2, mockIRepositoryOptions3) - - const mockIRepositoryOptions4 = await SequelizeTestUtils.getTestIRepositoryOptions(db) - await IntegrationRepository.create(int3, mockIRepositoryOptions4) - - const found = await IntegrationRepository.findAllActive(PlatformType.TWITTER, 1, 100) - expect(found.length).toBe(2) - }) - - it('Should only find integrations for the desired platform', async () => { - const int1 = { - status: 'done', - platform: PlatformType.TWITTER, - } - - const int2 = { - status: 'active', - platform: PlatformType.DISCORD, - } - - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - await IntegrationRepository.create(int1, mockIRepositoryOptions) - - const mockIRepositoryOptions2 = await SequelizeTestUtils.getTestIRepositoryOptions(db) - await IntegrationRepository.create(int1, mockIRepositoryOptions2) - - const mockIRepositoryOptions3 = await SequelizeTestUtils.getTestIRepositoryOptions(db) - await IntegrationRepository.create(int2, mockIRepositoryOptions3) - - const found = await IntegrationRepository.findAllActive(PlatformType.TWITTER, 1, 100) - expect(found.length).toBe(2) - }) - - it('Should return an empty list if no integrations are found', async () => { - const found = await IntegrationRepository.findAllActive(PlatformType.TWITTER, 1, 100) - expect(found.length).toBe(0) - }) - }) -}) diff --git a/backend/src/database/repositories/__tests__/memberAttributeSettingsRepository.test.ts b/backend/src/database/repositories/__tests__/memberAttributeSettingsRepository.test.ts deleted file mode 100644 index dec49e71ca..0000000000 --- a/backend/src/database/repositories/__tests__/memberAttributeSettingsRepository.test.ts +++ /dev/null @@ -1,381 +0,0 @@ -import { Error400, Error404 } from '@crowd/common' -import { MemberAttributeType } from '@crowd/types' - -import SequelizeTestUtils from '../../utils/sequelizeTestUtils' -import MemberAttributeSettingsRepository from '../memberAttributeSettingsRepository' - -const db = null - -describe('MemberAttributeSettings tests', () => { - beforeEach(async () => { - await SequelizeTestUtils.wipeDatabase(db) - }) - - afterAll((done) => { - // Closing the DB connection allows Jest to exit successfully. - SequelizeTestUtils.closeConnection(db) - done() - }) - - describe('create method', () => { - it('Should create settings for a member attribute succesfully with default values', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - - const attribute = { - type: MemberAttributeType.BOOLEAN, - label: 'attribute 1', - name: 'attribute1', - } - - const attributeCreated = await MemberAttributeSettingsRepository.create( - attribute, - mockIRepositoryOptions, - ) - - attributeCreated.createdAt = (attributeCreated.createdAt as any).toISOString().split('T')[0] - attributeCreated.updatedAt = (attributeCreated.updatedAt as any).toISOString().split('T')[0] - - const attributeExpected = { - id: attributeCreated.id, - type: attribute.type, - label: attribute.label, - name: attribute.name, - options: [], - show: true, - canDelete: true, - createdAt: SequelizeTestUtils.getNowWithoutTime(), - updatedAt: SequelizeTestUtils.getNowWithoutTime(), - tenantId: mockIRepositoryOptions.currentTenant.id, - createdById: mockIRepositoryOptions.currentUser.id, - updatedById: mockIRepositoryOptions.currentUser.id, - } - - expect(attributeCreated).toStrictEqual(attributeExpected) - }) - - it('Should create settings for a member attribute succesfully with given values', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - - const attribute = { - type: MemberAttributeType.BOOLEAN, - label: 'attribute 1', - name: 'attribute1', - canDelete: false, - show: false, - } - - const attributeCreated = await MemberAttributeSettingsRepository.create( - attribute, - mockIRepositoryOptions, - ) - - attributeCreated.createdAt = (attributeCreated.createdAt as any).toISOString().split('T')[0] - attributeCreated.updatedAt = (attributeCreated.updatedAt as any).toISOString().split('T')[0] - - const attributeExpected = { - id: attributeCreated.id, - type: attribute.type, - label: attribute.label, - name: attribute.name, - show: false, - options: [], - canDelete: false, - createdAt: SequelizeTestUtils.getNowWithoutTime(), - updatedAt: SequelizeTestUtils.getNowWithoutTime(), - tenantId: mockIRepositoryOptions.currentTenant.id, - createdById: mockIRepositoryOptions.currentUser.id, - updatedById: mockIRepositoryOptions.currentUser.id, - } - - expect(attributeCreated).toStrictEqual(attributeExpected) - }) - - it('Should throw unique constraint error for creation of already existing member attributes with same name in the same tenant', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - - const attribute = { - type: MemberAttributeType.BOOLEAN, - label: 'attribute 1', - name: 'attribute1', - } - - await MemberAttributeSettingsRepository.create(attribute, mockIRepositoryOptions) - - await expect(() => - MemberAttributeSettingsRepository.create( - { type: MemberAttributeType.STRING, label: 'some label', name: 'attribute1' }, - mockIRepositoryOptions, - ), - ).rejects.toThrow() - }) - - it('Should throw not null error if no name, label or type is given', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - - // no type - await expect(() => - MemberAttributeSettingsRepository.create( - { type: undefined, label: 'attribute 1', name: 'attribute1' }, - mockIRepositoryOptions, - ), - ).rejects.toThrow() - - // no label - await expect(() => - MemberAttributeSettingsRepository.create( - { type: MemberAttributeType.BOOLEAN, name: 'attribute1', label: undefined }, - mockIRepositoryOptions, - ), - ).rejects.toThrow() - - // no name - await expect(() => - MemberAttributeSettingsRepository.create( - { type: MemberAttributeType.BOOLEAN, label: 'attribute 1' }, - mockIRepositoryOptions, - ), - ).rejects.toThrow() - }) - }) - - describe('findById method', () => { - it('Should successfully find created member attribute by id', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - - const attribute = { - type: MemberAttributeType.BOOLEAN, - label: 'attribute 1', - name: 'attribute1', - } - - const attributeCreated = await MemberAttributeSettingsRepository.create( - attribute, - mockIRepositoryOptions, - ) - - const attributeExpected = { - id: attributeCreated.id, - type: attribute.type, - label: attribute.label, - name: attribute.name, - show: true, - canDelete: true, - options: [], - createdAt: SequelizeTestUtils.getNowWithoutTime(), - updatedAt: SequelizeTestUtils.getNowWithoutTime(), - tenantId: mockIRepositoryOptions.currentTenant.id, - createdById: mockIRepositoryOptions.currentUser.id, - updatedById: mockIRepositoryOptions.currentUser.id, - } - - const attributeById = await MemberAttributeSettingsRepository.findById( - attributeCreated.id, - mockIRepositoryOptions, - ) - - attributeById.createdAt = (attributeCreated.createdAt as any).toISOString().split('T')[0] - attributeById.updatedAt = (attributeCreated.updatedAt as any).toISOString().split('T')[0] - - expect(attributeById).toStrictEqual(attributeExpected) - }) - }) - - describe('findAndCountAll method', () => { - it('Should find and count all member attributes, with various filters', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - - const attribute1 = await MemberAttributeSettingsRepository.create( - { type: MemberAttributeType.BOOLEAN, label: 'a label', name: 'attribute1' }, - mockIRepositoryOptions, - ) - - const attribute2 = await MemberAttributeSettingsRepository.create( - { type: MemberAttributeType.STRING, label: 'a label', name: 'attribute2', show: false }, - mockIRepositoryOptions, - ) - - const attribute3 = await MemberAttributeSettingsRepository.create( - { - type: MemberAttributeType.STRING, - label: 'some other label', - name: 'attribute3', - show: false, - canDelete: false, - }, - mockIRepositoryOptions, - ) - - // filter by type - let attributes = await MemberAttributeSettingsRepository.findAndCountAll( - { filter: { type: MemberAttributeType.BOOLEAN } }, - mockIRepositoryOptions, - ) - - expect(attributes.count).toEqual(1) - expect(attributes.rows).toStrictEqual([attribute1]) - - // filter by id - attributes = await MemberAttributeSettingsRepository.findAndCountAll( - { filter: { id: attribute2.id } }, - mockIRepositoryOptions, - ) - - expect(attributes.count).toEqual(1) - expect(attributes.rows).toStrictEqual([attribute2]) - - // filter by label - attributes = await MemberAttributeSettingsRepository.findAndCountAll( - { filter: { label: 'a label' } }, - mockIRepositoryOptions, - ) - - expect(attributes.count).toEqual(2) - expect(attributes.rows).toStrictEqual([attribute2, attribute1]) - - // filter by name - attributes = await MemberAttributeSettingsRepository.findAndCountAll( - { filter: { name: 'attribute3' } }, - mockIRepositoryOptions, - ) - - expect(attributes.count).toEqual(1) - expect(attributes.rows).toStrictEqual([attribute3]) - - // filter by show - attributes = await MemberAttributeSettingsRepository.findAndCountAll( - { filter: { show: false } }, - mockIRepositoryOptions, - ) - - expect(attributes.count).toEqual(2) - expect(attributes.rows).toStrictEqual([attribute3, attribute2]) - - // filter by canDelete - attributes = await MemberAttributeSettingsRepository.findAndCountAll( - { filter: { canDelete: true } }, - mockIRepositoryOptions, - ) - - expect(attributes.count).toEqual(2) - expect(attributes.rows).toStrictEqual([attribute2, attribute1]) - - // filter by createdAt between createdAt a1 and a3 - attributes = await MemberAttributeSettingsRepository.findAndCountAll( - { - filter: { - createdAtRange: [attribute1.createdAt, attribute3.createdAt], - }, - }, - mockIRepositoryOptions, - ) - - expect(attributes.count).toEqual(3) - expect(attributes.rows).toStrictEqual([attribute3, attribute2, attribute1]) - - // filter by createdAt <= att2.createdAt - attributes = await MemberAttributeSettingsRepository.findAndCountAll( - { - filter: { - createdAtRange: [null, attribute2.createdAt], - }, - }, - mockIRepositoryOptions, - ) - expect(attributes.count).toEqual(2) - expect(attributes.rows).toStrictEqual([attribute2, attribute1]) - - // filter by createdAt <= att1.createdAt - attributes = await MemberAttributeSettingsRepository.findAndCountAll( - { - filter: { - createdAtRange: [null, attribute1.createdAt], - }, - }, - mockIRepositoryOptions, - ) - expect(attributes.count).toEqual(1) - expect(attributes.rows).toStrictEqual([attribute1]) - }) - }) - - describe('update method', () => { - it('Should succesfully update previously created attribute', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - - const attribute = await MemberAttributeSettingsRepository.create( - { type: MemberAttributeType.BOOLEAN, label: 'attribute 1', name: 'attribute1' }, - mockIRepositoryOptions, - ) - - const attributeUpdated = await MemberAttributeSettingsRepository.update( - attribute.id, - { - type: MemberAttributeType.STRING, - label: 'some other label', - name: 'some name', - show: false, - canDelete: false, - }, - mockIRepositoryOptions, - ) - - const attributeExpected = { - id: attribute.id, - type: attributeUpdated.type, - label: attributeUpdated.label, - name: attributeUpdated.name, - show: attributeUpdated.show, - canDelete: attributeUpdated.canDelete, - options: [], - createdAt: attribute.createdAt, - updatedAt: attributeUpdated.updatedAt, - tenantId: mockIRepositoryOptions.currentTenant.id, - createdById: mockIRepositoryOptions.currentUser.id, - updatedById: mockIRepositoryOptions.currentUser.id, - } - - expect(attributeUpdated).toStrictEqual(attributeExpected) - }) - - it('Should throw 404 error when trying to update non existent attribute', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - - const { randomUUID } = require('crypto') - - await expect(() => - MemberAttributeSettingsRepository.update( - randomUUID(), - { type: 'some-type' } as any, - mockIRepositoryOptions, - ), - ).rejects.toThrowError(new Error404()) - }) - }) - - describe('destroy method', () => { - it('Should succesfully destroy previously created attribute', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - - const attribute = await MemberAttributeSettingsRepository.create( - { type: MemberAttributeType.BOOLEAN, label: 'attribute 1', name: 'attribute1' }, - mockIRepositoryOptions, - ) - - await MemberAttributeSettingsRepository.destroy(attribute.id, mockIRepositoryOptions) - - await expect(() => - MemberAttributeSettingsRepository.findById(attribute.id, mockIRepositoryOptions), - ).rejects.toThrowError(new Error404()) - }) - - it('Should throw 404 when trying to destroy a non existent microservice', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - - const { randomUUID } = require('crypto') - - await expect(() => - MemberAttributeSettingsRepository.destroy(randomUUID(), mockIRepositoryOptions), - ).rejects.toThrowError(new Error404()) - }) - }) -}) diff --git a/backend/src/database/repositories/__tests__/microserviceRepository.test.ts b/backend/src/database/repositories/__tests__/microserviceRepository.test.ts deleted file mode 100644 index a921d24e00..0000000000 --- a/backend/src/database/repositories/__tests__/microserviceRepository.test.ts +++ /dev/null @@ -1,464 +0,0 @@ -import { Error404 } from '@crowd/common' - -import SequelizeTestUtils from '../../utils/sequelizeTestUtils' -import MicroserviceRepository from '../microserviceRepository' - -const db = null - -describe('MicroserviceRepository tests', () => { - beforeEach(async () => { - await SequelizeTestUtils.wipeDatabase(db) - }) - - afterAll((done) => { - // Closing the DB connection allows Jest to exit successfully. - SequelizeTestUtils.closeConnection(db) - done() - }) - - describe('create method', () => { - it('Should create a microservice succesfully with default values', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - - const microservice2Add = { type: 'members_score' } - - const microserviceCreated = await MicroserviceRepository.create( - microservice2Add, - mockIRepositoryOptions, - ) - - microserviceCreated.createdAt = microserviceCreated.createdAt.toISOString().split('T')[0] - microserviceCreated.updatedAt = microserviceCreated.updatedAt.toISOString().split('T')[0] - - const microserviceExpected = { - id: microserviceCreated.id, - init: false, - running: false, - type: microservice2Add.type, - variant: 'default', - settings: {}, - importHash: null, - createdAt: SequelizeTestUtils.getNowWithoutTime(), - updatedAt: SequelizeTestUtils.getNowWithoutTime(), - tenantId: mockIRepositoryOptions.currentTenant.id, - createdById: mockIRepositoryOptions.currentUser.id, - updatedById: mockIRepositoryOptions.currentUser.id, - } - - expect(microserviceCreated).toStrictEqual(microserviceExpected) - }) - - it('Should create a microservice succesfully with given values', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - - const microservice2Add = { - init: true, - running: true, - type: 'members_score', - variant: 'premium', - settings: { testSettingsField: 'test' }, - } - - const microserviceCreated = await MicroserviceRepository.create( - microservice2Add, - mockIRepositoryOptions, - ) - - microserviceCreated.createdAt = microserviceCreated.createdAt.toISOString().split('T')[0] - microserviceCreated.updatedAt = microserviceCreated.updatedAt.toISOString().split('T')[0] - - const microserviceExpected = { - id: microserviceCreated.id, - init: microservice2Add.init, - running: microservice2Add.running, - type: microservice2Add.type, - variant: microservice2Add.variant, - settings: microservice2Add.settings, - importHash: null, - createdAt: SequelizeTestUtils.getNowWithoutTime(), - updatedAt: SequelizeTestUtils.getNowWithoutTime(), - tenantId: mockIRepositoryOptions.currentTenant.id, - createdById: mockIRepositoryOptions.currentUser.id, - updatedById: mockIRepositoryOptions.currentUser.id, - } - - expect(microserviceCreated).toStrictEqual(microserviceExpected) - }) - - it('Should throw unique constraint error for creation of already existing type microservice in the same tenant', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - - const microservice1 = { - init: true, - running: true, - type: 'members_score', - variant: 'premium', - settings: { testSettingsField: 'test' }, - } - - await MicroserviceRepository.create(microservice1, mockIRepositoryOptions) - - await expect(() => - MicroserviceRepository.create({ type: 'members_score' }, mockIRepositoryOptions), - ).rejects.toThrow() - }) - - it('Should throw not null error if no type is given', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - - const microservice2Add = { - init: true, - running: true, - variant: 'premium', - settings: { testSettingsField: 'test' }, - } - - await expect(() => - MicroserviceRepository.create(microservice2Add, mockIRepositoryOptions), - ).rejects.toThrow() - }) - }) - - describe('findById method', () => { - it('Should successfully find created microservice by id', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - - const microservice2Add = { type: 'members_score' } - - const microserviceCreated = await MicroserviceRepository.create( - microservice2Add, - mockIRepositoryOptions, - ) - - const microserviceExpected = { - id: microserviceCreated.id, - init: false, - running: false, - type: microservice2Add.type, - variant: 'default', - settings: {}, - importHash: null, - createdAt: SequelizeTestUtils.getNowWithoutTime(), - updatedAt: SequelizeTestUtils.getNowWithoutTime(), - tenantId: mockIRepositoryOptions.currentTenant.id, - createdById: mockIRepositoryOptions.currentUser.id, - updatedById: mockIRepositoryOptions.currentUser.id, - } - - const microserviceById = await MicroserviceRepository.findById( - microserviceCreated.id, - mockIRepositoryOptions, - ) - - microserviceById.createdAt = microserviceById.createdAt.toISOString().split('T')[0] - microserviceById.updatedAt = microserviceById.updatedAt.toISOString().split('T')[0] - - expect(microserviceById).toStrictEqual(microserviceExpected) - }) - - it('Should throw 404 error when no microservice found with given id', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - const { randomUUID } = require('crypto') - - await expect(() => - MicroserviceRepository.findById(randomUUID(), mockIRepositoryOptions), - ).rejects.toThrowError(new Error404()) - }) - }) - - describe('filterIdsInTenant method', () => { - it('Should return the given ids of previously created microservice entities', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - - const microservice1Created = await MicroserviceRepository.create( - { type: 'members_score' }, - mockIRepositoryOptions, - ) - const microservice2Created = await MicroserviceRepository.create( - { type: 'second' }, - mockIRepositoryOptions, - ) - - const filterIdsReturned = await MicroserviceRepository.filterIdsInTenant( - [microservice1Created.id, microservice2Created.id], - mockIRepositoryOptions, - ) - - expect(filterIdsReturned).toStrictEqual([microservice1Created.id, microservice2Created.id]) - }) - - it('Should only return the ids of previously created microservices and filter random uuids out', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - - const microserviceCreated = await MicroserviceRepository.create( - { type: 'members_score' }, - mockIRepositoryOptions, - ) - - const { randomUUID } = require('crypto') - - const filterIdsReturned = await MicroserviceRepository.filterIdsInTenant( - [microserviceCreated.id, randomUUID(), randomUUID()], - mockIRepositoryOptions, - ) - - expect(filterIdsReturned).toStrictEqual([microserviceCreated.id]) - }) - - it('Should return an empty array for an irrelevant tenant', async () => { - let mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - - const microserviceCreated = await MicroserviceRepository.create( - { type: 'members_score' }, - mockIRepositoryOptions, - ) - - // create a new tenant and bind options to it - mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - - const filterIdsReturned = await MicroserviceRepository.filterIdsInTenant( - [microserviceCreated.id], - mockIRepositoryOptions, - ) - - expect(filterIdsReturned).toStrictEqual([]) - }) - }) - - describe('findAndCountAll method', () => { - it('Should find and count all microservices, with various filters', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - - const microservice1Created = await MicroserviceRepository.create( - { type: 'members_score', variant: 'premium' }, - mockIRepositoryOptions, - ) - - const microservice2Created = await MicroserviceRepository.create( - { type: 'second', variant: 'premium' }, - mockIRepositoryOptions, - ) - - // Filter by type - let microservices = await MicroserviceRepository.findAndCountAll( - { filter: { type: 'members_score' } }, - mockIRepositoryOptions, - ) - - expect(microservices.count).toEqual(1) - expect(microservices.rows).toStrictEqual([microservice1Created]) - - // Filter by id - microservices = await MicroserviceRepository.findAndCountAll( - { filter: { id: microservice1Created.id } }, - mockIRepositoryOptions, - ) - - expect(microservices.count).toEqual(1) - expect(microservices.rows).toStrictEqual([microservice1Created]) - - // Filter by variant - microservices = await MicroserviceRepository.findAndCountAll( - { filter: { variant: 'premium' } }, - mockIRepositoryOptions, - ) - - expect(microservices.count).toEqual(2) - expect(microservices.rows).toStrictEqual([microservice2Created, microservice1Created]) - }) - }) - - describe('update method', () => { - it('Should succesfully update previously created microservice', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - - const microserviceCreated = await MicroserviceRepository.create( - { type: 'twitter_followers' }, - mockIRepositoryOptions, - ) - - const microserviceUpdated = await MicroserviceRepository.update( - microserviceCreated.id, - { - init: true, - running: true, - variant: 'premium', - settings: { - testSettingAttribute: { - someAtt: 'test', - someOtherAtt: true, - }, - }, - }, - mockIRepositoryOptions, - ) - - expect(microserviceUpdated.updatedAt.getTime()).toBeGreaterThan( - microserviceUpdated.createdAt.getTime(), - ) - - const microserviceExpected = { - id: microserviceCreated.id, - init: microserviceUpdated.init, - running: microserviceUpdated.running, - type: microserviceCreated.type, - variant: microserviceUpdated.variant, - settings: microserviceUpdated.settings, - importHash: null, - createdAt: microserviceCreated.createdAt, - updatedAt: microserviceUpdated.updatedAt, - tenantId: mockIRepositoryOptions.currentTenant.id, - createdById: mockIRepositoryOptions.currentUser.id, - updatedById: mockIRepositoryOptions.currentUser.id, - } - - expect(microserviceUpdated).toStrictEqual(microserviceExpected) - }) - - it('Should throw 404 error when trying to update non existent microservice', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - - const { randomUUID } = require('crypto') - - await expect(() => - MicroserviceRepository.update(randomUUID(), { type: 'some-type' }, mockIRepositoryOptions), - ).rejects.toThrowError(new Error404()) - }) - }) - describe('destroy method', () => { - it('Should succesfully destroy previously created microservice', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - - const microserviceCreated = await MicroserviceRepository.create( - { type: 'members_score', variant: 'premium' }, - mockIRepositoryOptions, - ) - - await MicroserviceRepository.destroy(microserviceCreated.id, mockIRepositoryOptions) - - // Try selecting it after destroy, should throw 404 - await expect(() => - MicroserviceRepository.findById(microserviceCreated.id, mockIRepositoryOptions), - ).rejects.toThrowError(new Error404()) - }) - - it('Should throw 404 when trying to destroy a non existent microservice', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - - const { randomUUID } = require('crypto') - - await expect(() => - MicroserviceRepository.destroy(randomUUID(), mockIRepositoryOptions), - ).rejects.toThrowError(new Error404()) - }) - }) - - describe('Find all available microservices', () => { - it('Should find a single available microservices for a type', async () => { - const ms1 = { - type: 'twitter-followers', - running: false, - init: false, - variant: 'default', - settings: {}, - } - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - await MicroserviceRepository.create(ms1, mockIRepositoryOptions) - - const found: any = await MicroserviceRepository.findAllByType('twitter-followers', 1, 100) - expect(found[0].tenantId).toBeDefined() - expect(found.length).toBe(1) - }) - - it('Should find all available microservices for a type, multiple available', async () => { - const ms1 = { - type: 'twitter-followers', - running: false, - init: false, - variant: 'default', - settings: {}, - } - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - await MicroserviceRepository.create(ms1, mockIRepositoryOptions) - - const mockIRepositoryOptions2 = await SequelizeTestUtils.getTestIRepositoryOptions(db) - await MicroserviceRepository.create(ms1, mockIRepositoryOptions2) - - const found = await MicroserviceRepository.findAllByType('twitter-followers', 1, 100) - expect(found.length).toBe(2) - }) - - it('Should only find non-running microservices', async () => { - const ms1 = { - type: 'twitter-followers', - running: false, - init: false, - variant: 'default', - settings: {}, - } - - const ms2 = { - type: 'twitter-followers', - running: true, - init: false, - variant: 'default', - settings: {}, - } - - const ms3 = { - type: 'twitter-followers', - running: false, - init: false, - variant: 'default', - settings: {}, - } - - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - await MicroserviceRepository.create(ms1, mockIRepositoryOptions) - - const mockIRepositoryOptions2 = await SequelizeTestUtils.getTestIRepositoryOptions(db) - await MicroserviceRepository.create(ms2, mockIRepositoryOptions2) - - const mockIRepositoryOptions3 = await SequelizeTestUtils.getTestIRepositoryOptions(db) - await MicroserviceRepository.create(ms3, mockIRepositoryOptions3) - - const found = await MicroserviceRepository.findAllByType('twitter-followers', 1, 100) - expect(found.length).toBe(2) - }) - - it('Should only find microservices for the desired type', async () => { - const ms1 = { - type: 'twitter-followers', - running: false, - init: false, - variant: 'default', - settings: {}, - } - - const ms2 = { - type: 'members_score', - running: false, - init: false, - variant: 'default', - settings: {}, - } - - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - await MicroserviceRepository.create(ms1, mockIRepositoryOptions) - - const mockIRepositoryOptions2 = await SequelizeTestUtils.getTestIRepositoryOptions(db) - await MicroserviceRepository.create(ms1, mockIRepositoryOptions2) - - const mockIRepositoryOptions3 = await SequelizeTestUtils.getTestIRepositoryOptions(db) - await MicroserviceRepository.create(ms2, mockIRepositoryOptions3) - - const found = await MicroserviceRepository.findAllByType('twitter-followers', 1, 100) - expect(found.length).toBe(2) - }) - - it('Should return an empty list if no integrations are found', async () => { - const found = await MicroserviceRepository.findAllByType('twitter-followers', 1, 100) - expect(found.length).toBe(0) - }) - }) -}) diff --git a/backend/src/database/repositories/__tests__/recurringEmailsHistoryRepository.test.ts b/backend/src/database/repositories/__tests__/recurringEmailsHistoryRepository.test.ts deleted file mode 100644 index 7126146bf2..0000000000 --- a/backend/src/database/repositories/__tests__/recurringEmailsHistoryRepository.test.ts +++ /dev/null @@ -1,153 +0,0 @@ -import { randomUUID } from 'crypto' - -import { - RecurringEmailType, - RecurringEmailsHistoryData, -} from '../../../types/recurringEmailsHistoryTypes' -import SequelizeTestUtils from '../../utils/sequelizeTestUtils' -import RecurringEmailsHistoryRepository from '../recurringEmailsHistoryRepository' - -const db = null - -describe('RecurringEmailsHistory tests', () => { - beforeEach(async () => { - await SequelizeTestUtils.wipeDatabase(db) - }) - - afterAll((done) => { - // Closing the DB connection allows Jest to exit successfully. - SequelizeTestUtils.closeConnection(db) - done() - }) - - describe('create method', () => { - it('Should create recurring email history with given values', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - - const historyData: RecurringEmailsHistoryData = { - emailSentAt: '2023-01-02T00:00:00Z', - type: RecurringEmailType.WEEKLY_ANALYTICS, - emailSentTo: ['anil@crowd.dev', 'uros@crowd.dev'], - tenantId: mockIRepositoryOptions.currentTenant.id, - weekOfYear: '1', - } - - const rehRepository = new RecurringEmailsHistoryRepository(mockIRepositoryOptions) - const history = await rehRepository.create(historyData) - - expect(new Date(historyData.emailSentAt)).toStrictEqual(history.emailSentAt) - expect(historyData.emailSentTo).toStrictEqual(history.emailSentTo) - expect(historyData.tenantId).toStrictEqual(history.tenantId) - expect(historyData.weekOfYear).toStrictEqual(history.weekOfYear) - }) - - it('Should throw an error when mandatory fields are missing', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - - const rehRepository = new RecurringEmailsHistoryRepository(mockIRepositoryOptions) - await expect(() => - rehRepository.create({ - emailSentAt: '2023-01-02T00:00:00Z', - emailSentTo: ['anil@crowd.dev', 'uros@crowd.dev'], - tenantId: mockIRepositoryOptions.currentTenant.id, - type: undefined, - }), - ).rejects.toThrowError() - - await expect(() => - rehRepository.create({ - emailSentAt: undefined, - emailSentTo: ['anil@crowd.dev', 'uros@crowd.dev'], - tenantId: mockIRepositoryOptions.currentTenant.id, - weekOfYear: '1', - type: RecurringEmailType.WEEKLY_ANALYTICS, - }), - ).rejects.toThrowError() - - await expect(() => - rehRepository.create({ - emailSentAt: '2023-01-02T00:00:00Z', - emailSentTo: undefined, - tenantId: mockIRepositoryOptions.currentTenant.id, - weekOfYear: '1', - type: RecurringEmailType.WEEKLY_ANALYTICS, - }), - ).rejects.toThrowError() - - await expect(() => - rehRepository.create({ - emailSentAt: '2023-01-02T00:00:00Z', - emailSentTo: ['anil@crowd.dev', 'uros@crowd.dev'], - tenantId: undefined, - weekOfYear: '1', - type: RecurringEmailType.WEEKLY_ANALYTICS, - }), - ).rejects.toThrowError() - }) - }) - - describe('findById method', () => { - it('Should find historical receipt by id', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - - const historyData: RecurringEmailsHistoryData = { - emailSentAt: '2023-01-02T00:00:00Z', - emailSentTo: ['anil@crowd.dev', 'uros@crowd.dev'], - tenantId: mockIRepositoryOptions.currentTenant.id, - weekOfYear: '1', - type: RecurringEmailType.WEEKLY_ANALYTICS, - } - - const rehRepository = new RecurringEmailsHistoryRepository(mockIRepositoryOptions) - - const receiptCreated = await rehRepository.create(historyData) - const receiptFoundById = await rehRepository.findById(receiptCreated.id) - - expect(receiptFoundById).toStrictEqual(receiptCreated) - }) - - it('Should return null for non-existing receipt entry', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - const rehRepository = new RecurringEmailsHistoryRepository(mockIRepositoryOptions) - - const cache = await rehRepository.findById(randomUUID()) - expect(cache).toBeNull() - }) - }) - - describe('findByWeekOfYear method', () => { - it('Should find historical receipt by week of year', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - - const historyData: RecurringEmailsHistoryData = { - emailSentAt: '2023-01-02T00:00:00Z', - emailSentTo: ['anil@crowd.dev', 'uros@crowd.dev'], - tenantId: mockIRepositoryOptions.currentTenant.id, - weekOfYear: '1', - type: RecurringEmailType.EAGLE_EYE_DIGEST, - } - - const rehRepository = new RecurringEmailsHistoryRepository(mockIRepositoryOptions) - - const receiptCreated = await rehRepository.create(historyData) - - // should find recently created receipt - let receiptFound = await rehRepository.findByWeekOfYear( - mockIRepositoryOptions.currentTenant.id, - '1', - RecurringEmailType.EAGLE_EYE_DIGEST, - ) - - expect(receiptCreated).toStrictEqual(receiptFound) - - // shouldn't find any receipts - receiptFound = await rehRepository.findByWeekOfYear( - mockIRepositoryOptions.currentTenant.id, - '2', - RecurringEmailType.EAGLE_EYE_DIGEST, - ) - - expect(receiptFound).toBeNull() - }) - }) -}) diff --git a/backend/src/database/repositories/__tests__/tagRepository.test.ts b/backend/src/database/repositories/__tests__/tagRepository.test.ts deleted file mode 100644 index e9431f9edc..0000000000 --- a/backend/src/database/repositories/__tests__/tagRepository.test.ts +++ /dev/null @@ -1,296 +0,0 @@ -import { Error404 } from '@crowd/common' - -import SequelizeTestUtils from '../../utils/sequelizeTestUtils' -import TagRepository from '../tagRepository' - -const db = null - -describe('TagRepository tests', () => { - beforeEach(async () => { - await SequelizeTestUtils.wipeDatabase(db) - }) - - afterAll((done) => { - // Closing the DB connection allows Jest to exit successfully. - SequelizeTestUtils.closeConnection(db) - done() - }) - - describe('create method', () => { - it('Should create the given tag succesfully', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - - const tag2add = { name: 'test-tag' } - - const tagCreated = await TagRepository.create(tag2add, mockIRepositoryOptions) - - tagCreated.createdAt = tagCreated.createdAt.toISOString().split('T')[0] - tagCreated.updatedAt = tagCreated.updatedAt.toISOString().split('T')[0] - - const expectedTagCreated = { - id: tagCreated.id, - name: tag2add.name, - members: [], - importHash: null, - createdAt: SequelizeTestUtils.getNowWithoutTime(), - updatedAt: SequelizeTestUtils.getNowWithoutTime(), - deletedAt: null, - tenantId: mockIRepositoryOptions.currentTenant.id, - createdById: mockIRepositoryOptions.currentUser.id, - updatedById: mockIRepositoryOptions.currentUser.id, - } - expect(tagCreated).toStrictEqual(expectedTagCreated) - }) - - it('Should throw sequelize not null error -- name field is required', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - - const tag2add = {} - - await expect(() => TagRepository.create(tag2add, mockIRepositoryOptions)).rejects.toThrow() - }) - }) - - describe('findById method', () => { - it('Should successfully find created tag by id', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - - const tag2add = { name: 'test-tag' } - - const tagCreated = await TagRepository.create(tag2add, mockIRepositoryOptions) - - tagCreated.createdAt = tagCreated.createdAt.toISOString().split('T')[0] - tagCreated.updatedAt = tagCreated.updatedAt.toISOString().split('T')[0] - - const expectedTagFound = { - id: tagCreated.id, - name: tag2add.name, - members: [], - importHash: null, - createdAt: SequelizeTestUtils.getNowWithoutTime(), - updatedAt: SequelizeTestUtils.getNowWithoutTime(), - deletedAt: null, - tenantId: mockIRepositoryOptions.currentTenant.id, - createdById: mockIRepositoryOptions.currentUser.id, - updatedById: mockIRepositoryOptions.currentUser.id, - } - const tagById = await TagRepository.findById(tagCreated.id, mockIRepositoryOptions) - - tagById.createdAt = tagById.createdAt.toISOString().split('T')[0] - tagById.updatedAt = tagById.updatedAt.toISOString().split('T')[0] - - expect(tagById).toStrictEqual(expectedTagFound) - }) - - it('Should throw 404 error when no tag found with given id', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - const { randomUUID } = require('crypto') - - await expect(() => - TagRepository.findById(randomUUID(), mockIRepositoryOptions), - ).rejects.toThrowError(new Error404()) - }) - }) - - describe('filterIdsInTenant method', () => { - it('Should return the given ids of previously created tag entities', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - - const tag1 = { name: 'test1' } - const tag2 = { name: 'test2' } - - const tag1Created = await TagRepository.create(tag1, mockIRepositoryOptions) - const tag2Created = await TagRepository.create(tag2, mockIRepositoryOptions) - - const filterIdsReturned = await TagRepository.filterIdsInTenant( - [tag1Created.id, tag2Created.id], - mockIRepositoryOptions, - ) - - expect(filterIdsReturned).toStrictEqual([tag1Created.id, tag2Created.id]) - }) - - it('Should only return the ids of previously created tags and filter random uuids out', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - - const tag = { name: 'test1' } - - const tagCreated = await TagRepository.create(tag, mockIRepositoryOptions) - - const { randomUUID } = require('crypto') - - const filterIdsReturned = await TagRepository.filterIdsInTenant( - [tagCreated.id, randomUUID(), randomUUID()], - mockIRepositoryOptions, - ) - - expect(filterIdsReturned).toStrictEqual([tagCreated.id]) - }) - - it('Should return an empty array for an irrelevant tenant', async () => { - let mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - - const tag = { name: 'test' } - - const tagCreated = await TagRepository.create(tag, mockIRepositoryOptions) - - // create a new tenant and bind options to it - mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - - const filterIdsReturned = await TagRepository.filterIdsInTenant( - [tagCreated.id], - mockIRepositoryOptions, - ) - - expect(filterIdsReturned).toStrictEqual([]) - }) - }) - - describe('findAndCountAll method', () => { - it('Should find and count all tags, with various filters', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - - const tag1 = { name: 'test-tag' } - const tag2 = { name: 'test-tag-2' } - const tag3 = { name: 'another-tag' } - - const tag1Created = await TagRepository.create(tag1, mockIRepositoryOptions) - await new Promise((resolve) => { - setTimeout(resolve, 50) - }) - - const tag2Created = await TagRepository.create(tag2, mockIRepositoryOptions) - await new Promise((resolve) => { - setTimeout(resolve, 50) - }) - - const tag3Created = await TagRepository.create(tag3, mockIRepositoryOptions) - - // Test filter by name - // Current findAndCountAll uses wildcarded like statement so it matches both tags - let tags = await TagRepository.findAndCountAll( - { filter: { name: 'test-tag' } }, - mockIRepositoryOptions, - ) - - expect(tags.count).toEqual(2) - expect(tags.rows).toStrictEqual([tag2Created, tag1Created]) - - // Test filter by id - tags = await TagRepository.findAndCountAll( - { filter: { id: tag1Created.id } }, - mockIRepositoryOptions, - ) - - expect(tags.count).toEqual(1) - expect(tags.rows).toStrictEqual([tag1Created]) - - // Test filter by createdAt - find all between tag1.createdAt and tag3.createdAt - tags = await TagRepository.findAndCountAll( - { - filter: { - createdAtRange: [tag1Created.createdAt, tag3Created.createdAt], - }, - }, - mockIRepositoryOptions, - ) - - expect(tags.count).toEqual(3) - expect(tags.rows).toStrictEqual([tag3Created, tag2Created, tag1Created]) - - // Test filter by createdAt - find all where createdAt < tag2.createdAt - tags = await TagRepository.findAndCountAll( - { - filter: { - createdAtRange: [null, tag2Created.createdAt], - }, - }, - mockIRepositoryOptions, - ) - expect(tags.count).toEqual(2) - expect(tags.rows).toStrictEqual([tag2Created, tag1Created]) - - // Test filter by createdAt - find all where createdAt < tag1.createdAt - tags = await TagRepository.findAndCountAll( - { - filter: { - createdAtRange: [null, tag1Created.createdAt], - }, - }, - mockIRepositoryOptions, - ) - expect(tags.count).toEqual(1) - expect(tags.rows).toStrictEqual([tag1Created]) - }) - }) - - describe('update method', () => { - it('Should succesfully update previously created tag', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - - const tag1 = { name: 'test-tag' } - - const tagCreated = await TagRepository.create(tag1, mockIRepositoryOptions) - - const tagUpdated = await TagRepository.update( - tagCreated.id, - { name: 'updated-tag-name' }, - mockIRepositoryOptions, - ) - - expect(tagUpdated.updatedAt.getTime()).toBeGreaterThan(tagUpdated.createdAt.getTime()) - - const tagExpected = { - id: tagCreated.id, - name: tagUpdated.name, - importHash: null, - createdAt: tagCreated.createdAt, - updatedAt: tagUpdated.updatedAt, - deletedAt: null, - tenantId: mockIRepositoryOptions.currentTenant.id, - createdById: mockIRepositoryOptions.currentUser.id, - updatedById: mockIRepositoryOptions.currentUser.id, - members: [], - } - - expect(tagUpdated).toStrictEqual(tagExpected) - }) - - it('Should throw 404 error when trying to update non existent tag', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - - const { randomUUID } = require('crypto') - - await expect(() => - TagRepository.update(randomUUID(), { name: 'non-existent' }, mockIRepositoryOptions), - ).rejects.toThrowError(new Error404()) - }) - }) - - describe('destroy method', () => { - it('Should succesfully destroy previously created tag', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - - const tag = { name: 'test-tag' } - - const returnedTag = await TagRepository.create(tag, mockIRepositoryOptions) - - await TagRepository.destroy(returnedTag.id, mockIRepositoryOptions, true) - - // Try selecting it after destroy, should throw 404 - await expect(() => - TagRepository.findById(returnedTag.id, mockIRepositoryOptions), - ).rejects.toThrowError(new Error404()) - }) - - it('Should throw 404 when trying to destroy a non existent tag', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - - const { randomUUID } = require('crypto') - - await expect(() => - TagRepository.destroy(randomUUID(), mockIRepositoryOptions), - ).rejects.toThrowError(new Error404()) - }) - }) -}) diff --git a/backend/src/database/repositories/__tests__/tenantRepository.test.ts b/backend/src/database/repositories/__tests__/tenantRepository.test.ts deleted file mode 100644 index 4e0f61cef6..0000000000 --- a/backend/src/database/repositories/__tests__/tenantRepository.test.ts +++ /dev/null @@ -1,46 +0,0 @@ -import SequelizeTestUtils from '../../utils/sequelizeTestUtils' -import TenantRepository from '../tenantRepository' - -const db = null - -describe('TenantRepository tests', () => { - beforeEach(async () => { - await SequelizeTestUtils.wipeDatabase(db) - }) - - afterAll((done) => { - // Closing the DB connection allows Jest to exit successfully. - SequelizeTestUtils.closeConnection(db) - done() - }) - - describe('generateTenantUrl method', () => { - it('Should generate a url from name - 0 existing tenants with same url', async () => { - const options = await SequelizeTestUtils.getTestIRepositoryOptions(db) - const tenantName = 'some tenant Name with !@#_% non-alphanumeric characters' - - const generatedUrl = await TenantRepository.generateTenantUrl(tenantName, options) - const expectedGeneratedUrl = 'some-tenant-name-with-non-alphanumeric-characters' - - expect(generatedUrl).toStrictEqual(expectedGeneratedUrl) - }) - - it('Should generate a url from name - with existing tenant that has the same url', async () => { - const options = await SequelizeTestUtils.getTestIRepositoryOptions(db) - const tenantName = 'a tenant name' - - // create a tenant with url 'a-tenant-name' - await options.database.tenant.create({ - name: tenantName, - url: 'a-tenant-name', - }) - - // now generate function should return 'a-tenant-name-1' because it already exists - const generatedUrl = await TenantRepository.generateTenantUrl(tenantName, options) - - const expectedGeneratedUrl = 'a-tenant-name-1' - - expect(generatedUrl).toStrictEqual(expectedGeneratedUrl) - }) - }) -}) diff --git a/backend/src/database/repositories/__tests__/userRepository.test.ts b/backend/src/database/repositories/__tests__/userRepository.test.ts deleted file mode 100644 index a091978e45..0000000000 --- a/backend/src/database/repositories/__tests__/userRepository.test.ts +++ /dev/null @@ -1,121 +0,0 @@ -import { Error404 } from '@crowd/common' - -import Roles from '../../../security/roles' -import SequelizeTestUtils from '../../utils/sequelizeTestUtils' -import UserRepository from '../userRepository' - -const db = null - -describe('UserRepository tests', () => { - beforeEach(async () => { - await SequelizeTestUtils.wipeDatabase(db) - }) - - afterAll((done) => { - // Closing the DB connection allows Jest to exit successfully. - SequelizeTestUtils.closeConnection(db) - done() - }) - - describe('findAllUsersOfTenant method', () => { - it('Should find all related users of a tenant successfully', async () => { - // Getting options already creates one random user - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - - let allUsersOfTenant = ( - await UserRepository.findAllUsersOfTenant(mockIRepositoryOptions.currentTenant.id) - ).map((u) => SequelizeTestUtils.objectWithoutKey(u, 'tenants')) - - expect(allUsersOfTenant).toStrictEqual([ - mockIRepositoryOptions.currentUser.get({ plain: true }), - ]) - - // add more users to the test tenant - const randomUser2 = await SequelizeTestUtils.getRandomUser() - const user2 = await mockIRepositoryOptions.database.user.create(randomUser2) - - await mockIRepositoryOptions.database.tenantUser.create({ - roles: [Roles.values.admin], - status: 'active', - tenantId: mockIRepositoryOptions.currentTenant.id, - userId: user2.id, - }) - - allUsersOfTenant = ( - await UserRepository.findAllUsersOfTenant(mockIRepositoryOptions.currentTenant.id) - ).map((u) => SequelizeTestUtils.objectWithoutKey(u, 'tenants')) - - expect(allUsersOfTenant).toStrictEqual([ - mockIRepositoryOptions.currentUser.get({ plain: true }), - user2.get({ plain: true }), - ]) - - const randomUser3 = await SequelizeTestUtils.getRandomUser() - const user3 = await mockIRepositoryOptions.database.user.create(randomUser3) - - await mockIRepositoryOptions.database.tenantUser.create({ - roles: [Roles.values.admin], - status: 'active', - tenantId: mockIRepositoryOptions.currentTenant.id, - userId: user3.id, - }) - - allUsersOfTenant = ( - await UserRepository.findAllUsersOfTenant(mockIRepositoryOptions.currentTenant.id) - ).map((u) => SequelizeTestUtils.objectWithoutKey(u, 'tenants')) - - expect(allUsersOfTenant).toStrictEqual([ - mockIRepositoryOptions.currentUser.get({ plain: true }), - user2.get({ plain: true }), - user3.get({ plain: true }), - ]) - - // add other users and tenants that are non related to previous couples - await SequelizeTestUtils.getTestIRepositoryOptions(db) - - // users of the previous tenant should be the same - allUsersOfTenant = ( - await UserRepository.findAllUsersOfTenant(mockIRepositoryOptions.currentTenant.id) - ).map((u) => SequelizeTestUtils.objectWithoutKey(u, 'tenants')) - - expect(allUsersOfTenant).toStrictEqual([ - mockIRepositoryOptions.currentUser.get({ plain: true }), - user2.get({ plain: true }), - user3.get({ plain: true }), - ]) - - const tenantUsers = await mockIRepositoryOptions.database.tenantUser.findAll({ - tenantId: mockIRepositoryOptions.currentTenant.id, - }) - - // remove last user added to the tenant - await tenantUsers[2].destroy({ force: true }) - - allUsersOfTenant = ( - await UserRepository.findAllUsersOfTenant(mockIRepositoryOptions.currentTenant.id) - ).map((u) => SequelizeTestUtils.objectWithoutKey(u, 'tenants')) - - expect(allUsersOfTenant).toStrictEqual([ - mockIRepositoryOptions.currentUser.get({ plain: true }), - user2.get({ plain: true }), - ]) - - // remove first user added to the tenant - await tenantUsers[0].destroy({ force: true }) - - allUsersOfTenant = ( - await UserRepository.findAllUsersOfTenant(mockIRepositoryOptions.currentTenant.id) - ).map((u) => SequelizeTestUtils.objectWithoutKey(u, 'tenants')) - - expect(allUsersOfTenant).toStrictEqual([user2.get({ plain: true })]) - - // remove the last remaining user from the tenant - await tenantUsers[1].destroy({ force: true }) - - // function now should be throwing Error404 - await expect(() => - UserRepository.findAllUsersOfTenant(mockIRepositoryOptions.currentTenant.id), - ).rejects.toThrowError(new Error404()) - }) - }) -}) diff --git a/backend/src/database/repositories/filters/__tests__/queryParser.test.ts b/backend/src/database/repositories/filters/__tests__/queryParser.test.ts deleted file mode 100644 index 0c2f232cd4..0000000000 --- a/backend/src/database/repositories/filters/__tests__/queryParser.test.ts +++ /dev/null @@ -1,436 +0,0 @@ -import Sequelize from 'sequelize' - -import { generateUUIDv4 as uuid } from '@crowd/common' - -import SequelizeTestUtils from '../../../utils/sequelizeTestUtils' -import QueryParser from '../queryParser' - -const { Op } = Sequelize -const db = null - -describe('QueryParser tests', () => { - beforeEach(async () => { - await SequelizeTestUtils.wipeDatabase(db) - }) - - afterAll((done) => { - // Closing the DB connection allows Jest to exit successfully. - SequelizeTestUtils.closeConnection(db) - done() - }) - - describe('Simple tests', () => { - it('With empty values', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - const parser = new QueryParser({}, mockIRepositoryOptions) - const parsed = parser.parse({ - filter: {}, - orderBy: [], - }) - const expected = { - where: { - tenantId: mockIRepositoryOptions.currentTenant.id, - segmentId: mockIRepositoryOptions.currentSegments.map((s) => s.id), - }, - limit: 10, - offset: 0, - order: [], - } - expect(parsed).toStrictEqual(expected) - }) - it('With some filtering values', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - const parser = new QueryParser({}, mockIRepositoryOptions) - const parsed = parser.parse({ - filter: { - body: { - textContains: 'test', - }, - or: [{ channel: 'dev' }, { channel: 'bugs' }], - }, - orderBy: [], - }) - const expected = { - where: { - tenantId: mockIRepositoryOptions.currentTenant.id, - segmentId: mockIRepositoryOptions.currentSegments.map((s) => s.id), - body: { - [Op.iLike]: '%test%', - }, - [Op.or]: [{ channel: 'dev' }, { channel: 'bugs' }], - }, - limit: 10, - offset: 0, - order: [], - } - expect(parsed).toStrictEqual(expected) - }) - it('With some sorting values: list', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - const parser = new QueryParser({}, mockIRepositoryOptions) - const parsed = parser.parse({ - filter: {}, - orderBy: ['timestamp_DESC', 'channel_ASC'], - }) - const expected = { - where: { - tenantId: mockIRepositoryOptions.currentTenant.id, - segmentId: mockIRepositoryOptions.currentSegments.map((s) => s.id), - }, - limit: 10, - offset: 0, - order: [ - ['timestamp', 'DESC'], - ['channel', 'ASC'], - ], - } - expect(parsed).toStrictEqual(expected) - }) - - it('With some sorting values: string', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - const parser = new QueryParser({}, mockIRepositoryOptions) - const parsed = parser.parse({ - filter: {}, - orderBy: 'timestamp_DESC,channel_ASC', - }) - const expected = { - where: { - tenantId: mockIRepositoryOptions.currentTenant.id, - segmentId: mockIRepositoryOptions.currentSegments.map((s) => s.id), - }, - limit: 10, - offset: 0, - order: [ - ['timestamp', 'DESC'], - ['channel', 'ASC'], - ], - } - expect(parsed).toStrictEqual(expected) - }) - - it('With offset', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - const parser = new QueryParser({}, mockIRepositoryOptions) - const parsed = parser.parse({ - filter: {}, - orderBy: [], - offset: 10, - }) - const expected = { - where: { - tenantId: mockIRepositoryOptions.currentTenant.id, - segmentId: mockIRepositoryOptions.currentSegments.map((s) => s.id), - }, - limit: 10, - offset: 10, - order: [], - } - expect(parsed).toStrictEqual(expected) - }) - - it('With limit', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - const parser = new QueryParser({}, mockIRepositoryOptions) - const parsed = parser.parse({ - filter: {}, - orderBy: [], - limit: 100, - }) - const expected = { - where: { - tenantId: mockIRepositoryOptions.currentTenant.id, - segmentId: mockIRepositoryOptions.currentSegments.map((s) => s.id), - }, - limit: 100, - offset: 0, - order: [], - } - expect(parsed).toStrictEqual(expected) - }) - - it('With too large limit', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - const parser = new QueryParser({}, mockIRepositoryOptions) - const parsed = parser.parse({ - filter: {}, - orderBy: [], - limit: 210, - }) - const expected = { - where: { - tenantId: mockIRepositoryOptions.currentTenant.id, - segmentId: mockIRepositoryOptions.currentSegments.map((s) => s.id), - }, - limit: 200, - offset: 0, - order: [], - } - expect(parsed).toStrictEqual(expected) - }) - - it('With filtering, sorting, limit and offset', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - const parser = new QueryParser({}, mockIRepositoryOptions) - const parsed = parser.parse({ - filter: { - body: { - textContains: 'test', - }, - or: [{ channel: 'dev' }, { channel: 'bugs' }], - }, - orderBy: ['timestamp_DESC', 'channel_ASC'], - limit: 100, - offset: 10, - }) - const expected = { - where: { - tenantId: mockIRepositoryOptions.currentTenant.id, - segmentId: mockIRepositoryOptions.currentSegments.map((s) => s.id), - body: { - [Op.iLike]: '%test%', - }, - [Op.or]: [{ channel: 'dev' }, { channel: 'bugs' }], - }, - limit: 100, - offset: 10, - order: [ - ['timestamp', 'DESC'], - ['channel', 'ASC'], - ], - } - expect(parsed).toStrictEqual(expected) - }) - }) - - describe('Complex filtering tests', () => { - it('With nested fields', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - const parser = new QueryParser( - { - nestedFields: { - sentiment: 'sentiment.sentiment', - mood: 'sentiment.mood', - }, - }, - mockIRepositoryOptions, - ) - const parsed = parser.parse({ - filter: { - sentiment: { - gte: 0.5, - }, - or: [{ mood: 'happy' }, { mood: 'sad' }], - }, - orderBy: [], - }) - const expected = { - where: { - tenantId: mockIRepositoryOptions.currentTenant.id, - segmentId: mockIRepositoryOptions.currentSegments.map((s) => s.id), - 'sentiment.sentiment': { - [Op.gte]: 0.5, - }, - [Op.or]: [{ 'sentiment.mood': 'happy' }, { 'sentiment.mood': 'sad' }], - }, - limit: 10, - offset: 0, - order: [], - } - expect(parsed).toStrictEqual(expected) - }) - it('With complex operators', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - const parser = new QueryParser({}, mockIRepositoryOptions) - const parsed = parser.parse({ - filter: { - body: { - textContains: 'test', - }, - }, - orderBy: [], - }) - const expected = { - where: { - tenantId: mockIRepositoryOptions.currentTenant.id, - segmentId: mockIRepositoryOptions.currentSegments.map((s) => s.id), - body: { - [Op.iLike]: '%test%', - }, - }, - limit: 10, - offset: 0, - order: [], - } - expect(parsed).toStrictEqual(expected) - }) - it('With aggregators', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - const parser = new QueryParser( - { - aggregators: { - count: mockIRepositoryOptions.database.Sequelize.fn( - 'COUNT', - mockIRepositoryOptions.database.Sequelize.col('activities.id'), - ), - platform: Sequelize.literal(`"activities"."platform"`), - }, - }, - mockIRepositoryOptions, - ) - const parsed = parser.parse({ - filter: { - or: [ - { - platform: { - in: ['discord', 'github'], - }, - }, - { - count: { - gte: 10, - }, - }, - ], - }, - orderBy: [], - }) - const expected = { - having: { - [Op.or]: [ - { - [Op.and]: [ - Sequelize.where( - Sequelize.literal(`"activities"."platform"`), - Op.in, - Sequelize.literal(`('discord','github')`), - ), - ], - }, - { - [Op.and]: [ - Sequelize.where( - mockIRepositoryOptions.database.Sequelize.fn( - 'COUNT', - mockIRepositoryOptions.database.Sequelize.col('activities.id'), - ), - Op.gte, - 10, - ), - ], - }, - ], - }, - where: { - tenantId: mockIRepositoryOptions.currentTenant.id, - segmentId: mockIRepositoryOptions.currentSegments.map((s) => s.id), - }, - limit: 10, - offset: 0, - order: [], - } - expect(parsed).toStrictEqual(expected) - }) - it('With nested fields, complex operators and aggregators', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - const parser = new QueryParser( - { - nestedFields: { - sentiment: 'sentiment.sentiment', - mood: 'sentiment.mood', - }, - aggregators: { - count: mockIRepositoryOptions.database.Sequelize.fn( - 'COUNT', - mockIRepositoryOptions.database.Sequelize.col('activities.id'), - ), - platform: Sequelize.literal(`"activities"."platform"`), - }, - }, - mockIRepositoryOptions, - ) - - const parsed = parser.parse({ - filter: { - sentiment: { - gte: 0.5, - }, - or: [ - { - description: { - textContains: 'test', - }, - }, - { - and: [ - { - platform: { - in: ['discord', 'github'], - }, - }, - { - count: { - lt: 10, - }, - }, - ], - }, - ], - }, - orderBy: ['dueDate_DESC', 'createdAt_ASC'], - offset: 102, - limit: 101, - }) - const expected = { - where: { - tenantId: mockIRepositoryOptions.currentTenant.id, - segmentId: mockIRepositoryOptions.currentSegments.map((s) => s.id), - }, - having: { - 'sentiment.sentiment': { - [Op.gte]: 0.5, - }, - [Op.or]: [ - { - description: { - [Op.iLike]: '%test%', - }, - }, - { - [Op.and]: [ - { - [Op.and]: [ - Sequelize.where( - Sequelize.literal(`"activities"."platform"`), - Op.in, - Sequelize.literal(`('discord','github')`), - ), - ], - }, - { - [Op.and]: [ - Sequelize.where( - mockIRepositoryOptions.database.Sequelize.fn( - 'COUNT', - mockIRepositoryOptions.database.Sequelize.col('activities.id'), - ), - Op.lt, - 10, - ), - ], - }, - ], - }, - ], - }, - limit: 101, - offset: 102, - order: [ - ['dueDate', 'DESC'], - ['createdAt', 'ASC'], - ], - } - expect(parsed).toStrictEqual(expected) - }) - }) -}) diff --git a/backend/src/database/utils/__tests__/getUserContext.test.ts b/backend/src/database/utils/__tests__/getUserContext.test.ts deleted file mode 100644 index fb94c3bf6a..0000000000 --- a/backend/src/database/utils/__tests__/getUserContext.test.ts +++ /dev/null @@ -1,25 +0,0 @@ -import getUserContext from '../getUserContext' -import SequelizeTestUtils from '../sequelizeTestUtils' - -const db = null - -describe('Get user context tests', () => { - beforeEach(async () => { - await SequelizeTestUtils.wipeDatabase(db) - }) - - afterAll(async () => { - // Closing the DB connection allows Jest to exit successfully. - await SequelizeTestUtils.closeConnection(db) - }) - - describe('Get user context tests', () => { - it('Should get the user context for an existing tenant', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - const tenantId = mockIRepositoryOptions.currentTenant.dataValues.id - const userContext = await getUserContext(tenantId) - expect(userContext.currentTenant.dataValues.id).toBe(tenantId) - expect(userContext.currentUser).toBeDefined() - }) - }) -}) diff --git a/backend/src/database/utils/segmentTestUtils.ts b/backend/src/database/utils/segmentTestUtils.ts deleted file mode 100644 index 55dc0702a8..0000000000 --- a/backend/src/database/utils/segmentTestUtils.ts +++ /dev/null @@ -1,12 +0,0 @@ -import SegmentRepository from '../repositories/segmentRepository' - -export async function populateSegments(options) { - const repository = new SegmentRepository(options) - options.currentSegments = await Promise.all( - options.currentSegments.map(async (segment) => repository.findById(segment.id)), - ) -} - -export function switchSegments(options, segments) { - options.currentSegments = segments -} diff --git a/backend/src/database/utils/sequelizeTestUtils.ts b/backend/src/database/utils/sequelizeTestUtils.ts deleted file mode 100644 index 15a041442d..0000000000 --- a/backend/src/database/utils/sequelizeTestUtils.ts +++ /dev/null @@ -1,281 +0,0 @@ -import bcrypt from 'bcrypt' -import jwt from 'jsonwebtoken' -import moment from 'moment' -import { v4 as uuid } from 'uuid' - -import { getDbConnection } from '@crowd/data-access-layer/src/database' -import { getServiceLogger } from '@crowd/logging' -import { getClientSQL } from '@crowd/questdb' -import { getRedisClient } from '@crowd/redis' -import { getTemporalClient } from '@crowd/temporal' -import { SegmentStatus } from '@crowd/types' - -import { API_CONFIG, PRODUCT_DB_CONFIG, REDIS_CONFIG, TEMPORAL_CONFIG } from '../../conf' -import Roles from '../../security/roles' -import { IServiceOptions } from '../../services/IServiceOptions' -import { databaseInit } from '../databaseConnection' -import { IRepositoryOptions } from '../repositories/IRepositoryOptions' -import SettingsRepository from '../repositories/settingsRepository' -import TenantRepository from '../repositories/tenantRepository' -import UserRepository from '../repositories/userRepository' - -const logger = getServiceLogger() - -export default class SequelizeTestUtils { - static async wipeDatabase(db) { - db = await this.getDatabase(db) - - const tables = [ - '"organizationIdentities"', - '"automationExecutions"', - '"conversationSettings"', - '"auditLogs"', - '"automations"', - '"settings"', - '"activities"', - '"files"', - '"memberNoMerge"', - '"memberTags"', - '"microservices"', - '"memberToMerge"', - '"integrations"', - '"eagleEyeContents"', - '"eagleEyeActions"', - '"tags"', - - '"memberAttributeSettings"', - '"memberEnrichmentCache"', - '"memberSegmentAffiliations"', - '"memberSegments"', - '"memberOrganizations"', - '"membersSyncRemote"', - '"memberIdentities"', - '"members"', - - '"recurringEmailsHistory"', - '"integrationRuns"', - '"integrationStreams"', - '"segmentActivityChannels"', - '"conversations"', - '"incomingWebhooks"', - '"githubRepos"', - - '"organizationsSyncRemote"', - '"organizationSegments"', - '"organizationToMerge"', - '"organizationNoMerge"', - '"organizations"', - - '"tenantUsers"', - '"segments"', - '"tenants"', - '"users"', - ] - - try { - for (const table of tables) { - await db.sequelize.query(`delete from ${table};`) - } - } catch (e) { - logger.error(e) - throw e - } - } - - static async getDatabase(db?) { - if (!db) { - db = await databaseInit() - } - return db - } - - static async getTestIServiceOptions(db, tenantName?, tenantUrl?) { - db = await this.getDatabase(db) - - const randomTenant = - tenantName && tenantUrl ? this.getTenant(tenantName, tenantUrl) : this.getRandomTestTenant() - - const randomUser = await this.getRandomUser() - - let tenant = await db.tenant.create(randomTenant) - const segment = ( - await db.segment.create({ - url: tenant.url, - name: tenant.name, - parentName: tenant.name, - grandparentName: tenant.name, - slug: 'default', - parentSlug: 'default', - grandparentSlug: 'default', - status: SegmentStatus.ACTIVE, - sourceId: null, - sourceParentId: null, - tenantId: tenant.id, - }) - ).get({ plain: true }) - - let user = await db.user.create(randomUser) - - await db.tenantUser.create({ - roles: [Roles.values.admin], - status: 'active', - tenantId: tenant.id, - userId: user.id, - }) - - await SettingsRepository.findOrCreateDefault({}, { - language: 'en', - currentUser: user, - currentTenant: tenant, - currentSegments: [segment], - database: db, - } as IRepositoryOptions) - - tenant = await TenantRepository.findById(tenant.id, { - database: db, - } as IRepositoryOptions) - - user = await UserRepository.findById(user.id, { - database: db, - currentTenant: tenant, - bypassPermissionValidation: true, - } as IRepositoryOptions) - - const log = getServiceLogger() - - const redis = await getRedisClient(REDIS_CONFIG, true) - - return { - requestId: uuid(), - language: 'en', - currentUser: user, - currentTenant: tenant, - currentSegments: [segment], - database: db, - log, - redis, - temporal: await getTemporalClient(TEMPORAL_CONFIG), - productDb: await getDbConnection(PRODUCT_DB_CONFIG), - } as IServiceOptions - } - - static async getTestIRepositoryOptions(db): Promise { - db = await this.getDatabase(db) - - const randomTenant = this.getRandomTestTenant() - const randomUser = await this.getRandomUser() - - let tenant = await db.tenant.create(randomTenant) - const segment = ( - await db.segment.create({ - url: tenant.url, - name: tenant.name, - parentName: tenant.name, - grandparentName: tenant.name, - slug: 'default', - parentSlug: 'default', - grandparentSlug: 'default', - status: SegmentStatus.ACTIVE, - description: null, - sourceId: null, - sourceParentId: null, - tenantId: tenant.id, - }) - ).get({ plain: true }) - const user = await db.user.create(randomUser) - await db.tenantUser.create({ - roles: ['admin'], - status: 'active', - tenantId: tenant.id, - userId: user.id, - }) - - await SettingsRepository.findOrCreateDefault({}, { - language: 'en', - currentUser: user, - currentTenant: tenant, - currentSegments: [segment], - database: db, - } as IRepositoryOptions) - - tenant = await TenantRepository.findById(tenant.id, { - database: db, - } as IRepositoryOptions) - - const log = getServiceLogger() - const redis = await getRedisClient(REDIS_CONFIG, true) - const qdb = await getClientSQL() - - return { - requestId: uuid(), - language: 'en', - currentUser: user, - currentTenant: tenant, - currentSegments: [segment], - database: db, - qdb, - bypassPermissionValidation: true, - log, - redis, - temporal: await getTemporalClient(TEMPORAL_CONFIG), - productDb: await getDbConnection(PRODUCT_DB_CONFIG), - } as IRepositoryOptions - } - - static getRandomTestTenant() { - return this.getTenant(this.getRandomString('test-tenant'), this.getRandomString('url#')) - } - - static getTenant(name, url) { - return { - name, - url, - } - } - - static async getRandomUser() { - return { - email: this.getRandomString('test-user-', '@crowd.dev'), - password: await bcrypt.hash('12345', 12), - emailVerified: true, - } - } - - static getUserToken(mockIRepositoryOptions) { - const userId = mockIRepositoryOptions.currentUser.id - return jwt.sign({ id: userId }, API_CONFIG.jwtSecret, { - expiresIn: API_CONFIG.jwtExpiresIn, - }) - } - - static getRandomString(prefix = '', suffix = '') { - const randomTestSuffix = Math.trunc(Math.random() * 50000 + 1) - - return `${prefix}${randomTestSuffix}${suffix}` - } - - static getNowWithoutTime() { - return moment.utc().format('YYYY-MM-DD') - } - - static async closeConnection(db) { - db = await this.getDatabase(db) - db.sequelize.close() - } - - static objectWithoutKey(object, key) { - let objectWithoutKeys - if (typeof key === 'string') { - const { [key]: _, ...otherKeys } = object - objectWithoutKeys = otherKeys - } else if (Array.isArray(key)) { - objectWithoutKeys = key.reduce((acc, i) => { - const { [i]: _, ...otherKeys } = acc - acc = otherKeys - return acc - }, object) - } - - return objectWithoutKeys - } -} diff --git a/backend/src/serverless/integrations/usecases/__tests__/devto.api.test.ts b/backend/src/serverless/integrations/usecases/__tests__/devto.api.test.ts deleted file mode 100644 index 885b042002..0000000000 --- a/backend/src/serverless/integrations/usecases/__tests__/devto.api.test.ts +++ /dev/null @@ -1,105 +0,0 @@ -import { getArticleComments } from '../devto/getArticleComments' -import { getOrganizationArticles } from '../devto/getOrganizationArticles' -import { getUserById } from '../devto/getUser' -import { getUserArticles } from '../devto/getUserArticles' - -function expectDefinedNumber(val: any) { - expect(val).toBeDefined() - expect(typeof val).toBe('number') -} - -function expectDefinedString(val: any) { - expect(val).toBeDefined() - expect(typeof val).toBe('string') -} - -function expectDefinedStringOrNull(val: any) { - expect(val).toBeDefined() - expect(typeof val === 'string' || val === null).toBeTruthy() -} - -function expectDefinedArray(val: any) { - expect(val).toBeDefined() - expect(Array.isArray(val)).toBeTruthy() -} - -describe('Devto API tests', () => { - const organization = 'digitalocean' - const organizationArticleId = 524804 - - const username = 'kukicado' - const userId = 139953 - - it('Should return correct required properties when fetching organization articles', async () => { - const articles = await getOrganizationArticles(organization, 1, 1) - - expect(articles.length).toEqual(1) - - const article = articles[0] - expectDefinedNumber(article.id) - expectDefinedString(article.title) - expectDefinedString(article.description) - expectDefinedString(article.readable_publish_date) - expectDefinedArray(article.tag_list) - expectDefinedString(article.slug) - expectDefinedString(article.url) - expectDefinedNumber(article.comments_count) - expectDefinedString(article.published_at) - expectDefinedString(article.last_comment_at) - }) - - it('Should return the correct required properties when fetching article comments', async () => { - const comments = await getArticleComments(organizationArticleId) - expect(comments.length > 0).toBeTruthy() - - const comment = comments[0] - expectDefinedString(comment.id_code) - expectDefinedString(comment.created_at) - expectDefinedString(comment.body_html) - expectDefinedString(comment.body_html) - expectDefinedArray(comment.children) - expect(comment.user).toBeDefined() - - // check comment user properties - expectDefinedNumber(comment.user.user_id) - expectDefinedString(comment.user.name) - expectDefinedString(comment.user.username) - expectDefinedStringOrNull(comment.user.twitter_username) - expectDefinedStringOrNull(comment.user.github_username) - expectDefinedStringOrNull(comment.user.website_url) - expectDefinedString(comment.user.profile_image) - expectDefinedString(comment.user.profile_image_90) - }) - - it('Should return the correct required properties when fetching user articles', async () => { - const articles = await getUserArticles(username, 1, 1) - - expect(articles.length).toEqual(1) - - const article = articles[0] - expectDefinedNumber(article.id) - expectDefinedString(article.title) - expectDefinedString(article.description) - expectDefinedString(article.readable_publish_date) - expectDefinedArray(article.tag_list) - expectDefinedString(article.slug) - expectDefinedString(article.url) - expectDefinedNumber(article.comments_count) - expectDefinedString(article.published_at) - expectDefinedString(article.last_comment_at) - }) - - it('Should return the correct required properties when fetching a user', async () => { - const user = await getUserById(userId) - - expectDefinedNumber(user.id) - expectDefinedString(user.name) - expectDefinedString(user.username) - expectDefinedStringOrNull(user.twitter_username) - expectDefinedStringOrNull(user.github_username) - expectDefinedStringOrNull(user.website_url) - expectDefinedStringOrNull(user.location) - expectDefinedStringOrNull(user.summary) - expectDefinedString(user.profile_image) - }) -}) diff --git a/backend/src/serverless/integrations/usecases/__tests__/isInvalid.test.ts b/backend/src/serverless/integrations/usecases/__tests__/isInvalid.test.ts deleted file mode 100644 index 698b3c5008..0000000000 --- a/backend/src/serverless/integrations/usecases/__tests__/isInvalid.test.ts +++ /dev/null @@ -1,59 +0,0 @@ -import isInvalid from '../isInvalid' - -describe('Is invalid tests', () => { - it('It should return valid when the result is correct', async () => { - const result = { - value: { - followers: [1, 2, 3], - nextPage: '', - }, - } - expect(isInvalid(result, 'followers')).toBe(false) - }) - - it('It should also work for other keys', async () => { - const result = { - value: { - mentions: [1, 2, 3], - nextPage: '', - }, - } - expect(isInvalid(result, 'mentions')).toBe(false) - }) - - it('It return invalid when no value also work for other keys', async () => { - const result = { - broken: true, - } - expect(isInvalid(result, 'mentions')).toBe(true) - }) - - it('It return invalid when no key', async () => { - const result = { - value: { - broken: true, - }, - } - expect(isInvalid(result, 'mentions')).toBe(true) - }) - - it('It return invalid when wrong key', async () => { - const result = { - value: { - mentions: [1, 2, 3], - nextPage: '', - }, - } - expect(isInvalid(result, 'followers')).toBe(true) - }) - - it('It return valid when empty list', async () => { - const result = { - value: { - mentions: [], - nextPage: '', - }, - } - expect(isInvalid(result, 'mentions')).toBe(false) - }) -}) diff --git a/backend/src/services/__tests__/eagleEyeContentService.test.ts b/backend/src/services/__tests__/eagleEyeContentService.test.ts deleted file mode 100644 index 64187b5741..0000000000 --- a/backend/src/services/__tests__/eagleEyeContentService.test.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { EagleEyeActionType, EagleEyeContent } from '@crowd/types' - -import SequelizeTestUtils from '../../database/utils/sequelizeTestUtils' -import EagleEyeContentService from '../eagleEyeContentService' - -const db = null - -describe('EagleEyeContentService tests', () => { - beforeEach(async () => { - await SequelizeTestUtils.wipeDatabase(db) - }) - - afterAll(async () => { - // Closing the DB connection allows Jest to exit successfully. - await SequelizeTestUtils.closeConnection(db) - }) - - describe('upsert method', () => { - it('Should create or update a single content using URL field', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - - const content: EagleEyeContent = { - platform: 'reddit', - url: 'https://some-post-url', - post: { - title: 'post title', - body: 'post body', - }, - postedAt: '2020-05-27T15:13:30Z', - tenantId: mockIRepositoryOptions.currentTenant.id, - actions: [ - { - type: EagleEyeActionType.BOOKMARK, - timestamp: '2022-06-27T14:13:30Z', - }, - ], - } - - const service = new EagleEyeContentService(mockIRepositoryOptions) - const c1 = await service.upsert(content) - - let contents = await service.query({}) - - expect(contents.count).toBe(1) - expect(contents.rows).toStrictEqual([c1]) - - // upsert previous url with some new fields - const contentWithSameUrl: EagleEyeContent = { - platform: 'reddit', - url: 'https://some-post-url', - post: { - title: 'a brand new post title', - body: 'better post body', - }, - postedAt: '2020-05-27T15:13:30Z', - tenantId: mockIRepositoryOptions.currentTenant.id, - } - - const c1Upserted = await service.upsert(contentWithSameUrl) - - contents = await service.query({}) - expect(contents.count).toBe(1) - expect(contents.rows).toStrictEqual([c1Upserted]) - expect(c1Upserted.id).toEqual(c1.id) - expect(contents.rows[0].post).toStrictEqual(contentWithSameUrl.post) - }) - }) -}) diff --git a/backend/src/services/__tests__/integrationService.test.ts b/backend/src/services/__tests__/integrationService.test.ts deleted file mode 100644 index 9b9750cfe4..0000000000 --- a/backend/src/services/__tests__/integrationService.test.ts +++ /dev/null @@ -1,122 +0,0 @@ -import { PlatformType } from '@crowd/types' - -import SequelizeTestUtils from '../../database/utils/sequelizeTestUtils' -import IntegrationService from '../integrationService' - -const db = null - -describe('IntegrationService tests', () => { - beforeEach(async () => { - await SequelizeTestUtils.wipeDatabase(db) - }) - - afterAll(async () => { - // Closing the DB connection allows Jest to exit successfully. - await SequelizeTestUtils.closeConnection(db) - }) - - describe('createOrUpdate', () => { - it('Should create a new integration because platform does not exist yet', async () => { - const mockIServiceOptions = await SequelizeTestUtils.getTestIServiceOptions(db) - const integrationService = new IntegrationService(mockIServiceOptions) - - const integrationToCreate = { - platform: PlatformType.GITHUB, - token: '1234', - integrationIdentifier: '1234', - status: 'in-progress', - } - - let integrations = await integrationService.findAndCountAll({}) - expect(integrations.count).toEqual(0) - - await integrationService.createOrUpdate(integrationToCreate) - integrations = await integrationService.findAndCountAll({}) - - expect(integrations.count).toEqual(1) - }) - - it('Should update existing integration if platform already exists', async () => { - const mockIServiceOptions = await SequelizeTestUtils.getTestIServiceOptions(db) - const integrationService = new IntegrationService(mockIServiceOptions) - - const integrationToCreate = { - platform: PlatformType.GITHUB, - token: '1234', - integrationIdentifier: '1234', - status: 'in-progress', - } - - await integrationService.createOrUpdate(integrationToCreate) - let integrations = await integrationService.findAndCountAll({}) - expect(integrations.count).toEqual(1) - expect(integrations.rows[0].status).toEqual('in-progress') - - const integrationToUpdate = { - platform: PlatformType.GITHUB, - token: '1234', - integrationIdentifier: '1234', - status: 'done', - } - - await integrationService.createOrUpdate(integrationToUpdate) - integrations = await integrationService.findAndCountAll({}) - expect(integrations.count).toEqual(1) - expect(integrations.rows[0].status).toEqual('done') - }) - }) - - describe('Find all active integrations tests', () => { - it('Should find an empty list when there are no integrations', async () => { - const mockIServiceOptions = await SequelizeTestUtils.getTestIServiceOptions(db) - expect( - (await new IntegrationService(mockIServiceOptions).getAllActiveIntegrations()).count, - ).toBe(0) - }) - - it('Should return n for n active integrations', async () => { - const mockIServiceOptions = await SequelizeTestUtils.getTestIServiceOptions(db) - - await new IntegrationService(mockIServiceOptions).createOrUpdate({ - platform: PlatformType.SLACK, - status: 'done', - }) - expect( - (await new IntegrationService(mockIServiceOptions).getAllActiveIntegrations()).count, - ).toBe(1) - - await new IntegrationService(mockIServiceOptions).createOrUpdate({ - platform: PlatformType.GITHUB, - status: 'done', - }) - expect( - (await new IntegrationService(mockIServiceOptions).getAllActiveIntegrations()).count, - ).toBe(2) - }) - - it('Should return n for n active integrations when there are other integrations', async () => { - const mockIServiceOptions = await SequelizeTestUtils.getTestIServiceOptions(db) - - await new IntegrationService(mockIServiceOptions).createOrUpdate({ - platform: PlatformType.SLACK, - status: 'done', - }) - await new IntegrationService(mockIServiceOptions).createOrUpdate({ - platform: PlatformType.DISCORD, - status: 'in-progress', - }) - - expect( - (await new IntegrationService(mockIServiceOptions).getAllActiveIntegrations()).count, - ).toBe(1) - - await new IntegrationService(mockIServiceOptions).createOrUpdate({ - platform: PlatformType.GITHUB, - status: 'done', - }) - expect( - (await new IntegrationService(mockIServiceOptions).getAllActiveIntegrations()).count, - ).toBe(2) - }) - }) -}) diff --git a/backend/src/services/__tests__/memberAttributeSettingsService.test.ts b/backend/src/services/__tests__/memberAttributeSettingsService.test.ts deleted file mode 100644 index afaed3429b..0000000000 --- a/backend/src/services/__tests__/memberAttributeSettingsService.test.ts +++ /dev/null @@ -1,921 +0,0 @@ -/* eslint @typescript-eslint/no-unused-vars: 0 */ -import { Error400 } from '@crowd/common' -import { - DEVTO_MEMBER_ATTRIBUTES, - DISCORD_MEMBER_ATTRIBUTES, - GITHUB_MEMBER_ATTRIBUTES, - SLACK_MEMBER_ATTRIBUTES, - TWITTER_MEMBER_ATTRIBUTES, -} from '@crowd/integrations' -import { getServiceLogger } from '@crowd/logging' -import { RedisCache, getRedisClient } from '@crowd/redis' -import { MemberAttributeType } from '@crowd/types' - -import { REDIS_CONFIG } from '../../conf' -import SequelizeTestUtils from '../../database/utils/sequelizeTestUtils' -import MemberAttributeSettingsService from '../memberAttributeSettingsService' - -const log = getServiceLogger() - -let cache: RedisCache | undefined = undefined -const clearRedisCache = async () => { - if (!cache) { - const redis = await getRedisClient(REDIS_CONFIG) - cache = new RedisCache('memberAttributes', redis, log) - } - - await cache.deleteAll() -} - -const db = null -describe('MemberAttributeSettingService tests', () => { - beforeEach(async () => { - await SequelizeTestUtils.wipeDatabase(db) - await clearRedisCache() - }) - - afterAll(async () => { - // Closing the DB connection allows Jest to exit successfully. - await SequelizeTestUtils.closeConnection(db) - }) - - describe('createPredefined tests', () => { - it('Should create predefined github attributes', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - const as = new MemberAttributeSettingsService(mockIRepositoryOptions) - - const attributes = (await as.createPredefined(GITHUB_MEMBER_ATTRIBUTES)).map((attribute) => { - attribute.createdAt = (attribute.createdAt as any).toISOString().split('T')[0] - attribute.updatedAt = (attribute.updatedAt as any).toISOString().split('T')[0] - return attribute - }) - - const [ - isHireableCreated, - urlCreated, - websiteUrlCreated, - bioCreated, - locationCreated, - avatarUrlCreated, - companyCreated, - ] = attributes - - const [isHireable, url, websiteUrl, bio, location, avatarUrl, company] = - GITHUB_MEMBER_ATTRIBUTES - - const expected = [ - { - id: isHireableCreated.id, - createdAt: SequelizeTestUtils.getNowWithoutTime(), - updatedAt: SequelizeTestUtils.getNowWithoutTime(), - createdById: mockIRepositoryOptions.currentUser.id, - updatedById: mockIRepositoryOptions.currentUser.id, - tenantId: mockIRepositoryOptions.currentTenant.id, - options: [], - show: isHireable.show, - type: isHireable.type, - canDelete: isHireable.canDelete, - name: isHireable.name, - label: isHireable.label, - }, - { - id: urlCreated.id, - createdAt: SequelizeTestUtils.getNowWithoutTime(), - updatedAt: SequelizeTestUtils.getNowWithoutTime(), - createdById: mockIRepositoryOptions.currentUser.id, - updatedById: mockIRepositoryOptions.currentUser.id, - tenantId: mockIRepositoryOptions.currentTenant.id, - options: [], - show: url.show, - type: url.type, - canDelete: url.canDelete, - name: url.name, - label: url.label, - }, - { - id: websiteUrlCreated.id, - createdAt: SequelizeTestUtils.getNowWithoutTime(), - updatedAt: SequelizeTestUtils.getNowWithoutTime(), - createdById: mockIRepositoryOptions.currentUser.id, - updatedById: mockIRepositoryOptions.currentUser.id, - tenantId: mockIRepositoryOptions.currentTenant.id, - options: [], - show: websiteUrl.show, - type: websiteUrl.type, - canDelete: websiteUrl.canDelete, - name: websiteUrl.name, - label: websiteUrl.label, - }, - { - id: bioCreated.id, - createdAt: SequelizeTestUtils.getNowWithoutTime(), - updatedAt: SequelizeTestUtils.getNowWithoutTime(), - createdById: mockIRepositoryOptions.currentUser.id, - updatedById: mockIRepositoryOptions.currentUser.id, - tenantId: mockIRepositoryOptions.currentTenant.id, - options: [], - show: bio.show, - type: bio.type, - canDelete: bio.canDelete, - name: bio.name, - label: bio.label, - }, - { - id: locationCreated.id, - createdAt: SequelizeTestUtils.getNowWithoutTime(), - updatedAt: SequelizeTestUtils.getNowWithoutTime(), - createdById: mockIRepositoryOptions.currentUser.id, - updatedById: mockIRepositoryOptions.currentUser.id, - tenantId: mockIRepositoryOptions.currentTenant.id, - options: [], - show: location.show, - type: location.type, - canDelete: location.canDelete, - name: location.name, - label: location.label, - }, - { - id: avatarUrlCreated.id, - createdAt: SequelizeTestUtils.getNowWithoutTime(), - updatedAt: SequelizeTestUtils.getNowWithoutTime(), - createdById: mockIRepositoryOptions.currentUser.id, - updatedById: mockIRepositoryOptions.currentUser.id, - tenantId: mockIRepositoryOptions.currentTenant.id, - options: [], - show: avatarUrlCreated.show, - type: avatarUrlCreated.type, - canDelete: avatarUrlCreated.canDelete, - name: avatarUrlCreated.name, - label: avatarUrlCreated.label, - }, - { - id: companyCreated.id, - createdAt: SequelizeTestUtils.getNowWithoutTime(), - updatedAt: SequelizeTestUtils.getNowWithoutTime(), - createdById: mockIRepositoryOptions.currentUser.id, - updatedById: mockIRepositoryOptions.currentUser.id, - tenantId: mockIRepositoryOptions.currentTenant.id, - options: [], - show: company.show, - type: company.type, - canDelete: company.canDelete, - name: company.name, - label: company.label, - }, - ] - - expect(attributes).toEqual(expected) - }) - it('Should create predefined discord attributes', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - const as = new MemberAttributeSettingsService(mockIRepositoryOptions) - - const attributes = (await as.createPredefined(DISCORD_MEMBER_ATTRIBUTES)).map((attribute) => { - attribute.createdAt = (attribute.createdAt as any).toISOString().split('T')[0] - attribute.updatedAt = (attribute.updatedAt as any).toISOString().split('T')[0] - return attribute - }) - - const [idCreated, avatarUrlCreated] = attributes - - const [id, avatarUrl] = DISCORD_MEMBER_ATTRIBUTES - - const expected = [ - { - id: idCreated.id, - createdAt: SequelizeTestUtils.getNowWithoutTime(), - updatedAt: SequelizeTestUtils.getNowWithoutTime(), - createdById: mockIRepositoryOptions.currentUser.id, - updatedById: mockIRepositoryOptions.currentUser.id, - tenantId: mockIRepositoryOptions.currentTenant.id, - options: [], - show: id.show, - type: id.type, - canDelete: id.canDelete, - name: id.name, - label: id.label, - }, - { - id: avatarUrlCreated.id, - createdAt: SequelizeTestUtils.getNowWithoutTime(), - updatedAt: SequelizeTestUtils.getNowWithoutTime(), - createdById: mockIRepositoryOptions.currentUser.id, - updatedById: mockIRepositoryOptions.currentUser.id, - tenantId: mockIRepositoryOptions.currentTenant.id, - options: [], - show: avatarUrl.show, - type: avatarUrl.type, - canDelete: avatarUrl.canDelete, - name: avatarUrl.name, - label: avatarUrl.label, - }, - ] - - expect(attributes).toEqual(expected) - }) - - it('Should create predefined devto attributes', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - const as = new MemberAttributeSettingsService(mockIRepositoryOptions) - - const attributes = (await as.createPredefined(DEVTO_MEMBER_ATTRIBUTES)).map((attribute) => { - attribute.createdAt = (attribute.createdAt as any).toISOString().split('T')[0] - attribute.updatedAt = (attribute.updatedAt as any).toISOString().split('T')[0] - return attribute - }) - - const [idCreated, urlCreated, nameCreated, bioCreated, locationCreated] = attributes - - const [id, url, name, bio, location] = DEVTO_MEMBER_ATTRIBUTES - - const expected = [ - { - id: idCreated.id, - createdAt: SequelizeTestUtils.getNowWithoutTime(), - updatedAt: SequelizeTestUtils.getNowWithoutTime(), - createdById: mockIRepositoryOptions.currentUser.id, - updatedById: mockIRepositoryOptions.currentUser.id, - tenantId: mockIRepositoryOptions.currentTenant.id, - options: [], - show: id.show, - type: id.type, - canDelete: id.canDelete, - name: id.name, - label: id.label, - }, - { - id: urlCreated.id, - createdAt: SequelizeTestUtils.getNowWithoutTime(), - updatedAt: SequelizeTestUtils.getNowWithoutTime(), - createdById: mockIRepositoryOptions.currentUser.id, - updatedById: mockIRepositoryOptions.currentUser.id, - tenantId: mockIRepositoryOptions.currentTenant.id, - options: [], - show: url.show, - type: url.type, - canDelete: url.canDelete, - name: url.name, - label: url.label, - }, - { - id: nameCreated.id, - createdAt: SequelizeTestUtils.getNowWithoutTime(), - updatedAt: SequelizeTestUtils.getNowWithoutTime(), - createdById: mockIRepositoryOptions.currentUser.id, - updatedById: mockIRepositoryOptions.currentUser.id, - tenantId: mockIRepositoryOptions.currentTenant.id, - options: [], - show: name.show, - type: name.type, - canDelete: name.canDelete, - name: name.name, - label: name.label, - }, - { - id: bioCreated.id, - createdAt: SequelizeTestUtils.getNowWithoutTime(), - updatedAt: SequelizeTestUtils.getNowWithoutTime(), - createdById: mockIRepositoryOptions.currentUser.id, - updatedById: mockIRepositoryOptions.currentUser.id, - tenantId: mockIRepositoryOptions.currentTenant.id, - options: [], - show: bio.show, - type: bio.type, - canDelete: bio.canDelete, - name: bio.name, - label: bio.label, - }, - { - id: locationCreated.id, - createdAt: SequelizeTestUtils.getNowWithoutTime(), - updatedAt: SequelizeTestUtils.getNowWithoutTime(), - createdById: mockIRepositoryOptions.currentUser.id, - updatedById: mockIRepositoryOptions.currentUser.id, - tenantId: mockIRepositoryOptions.currentTenant.id, - options: [], - show: location.show, - type: location.type, - canDelete: location.canDelete, - name: location.name, - label: location.label, - }, - ] - - expect(attributes).toEqual(expected) - }) - it('Should create predefined twitter attributes', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - const as = new MemberAttributeSettingsService(mockIRepositoryOptions) - - const attributes = (await as.createPredefined(TWITTER_MEMBER_ATTRIBUTES)).map((attribute) => { - attribute.createdAt = (attribute.createdAt as any).toISOString().split('T')[0] - attribute.updatedAt = (attribute.updatedAt as any).toISOString().split('T')[0] - return attribute - }) - - const [idCreated, avatarUrlCreated, urlCreated, bioCreated, locationCreated] = attributes - - const [id, avatarUrl, url, bio, location] = TWITTER_MEMBER_ATTRIBUTES - - const expected = [ - { - id: idCreated.id, - createdAt: SequelizeTestUtils.getNowWithoutTime(), - updatedAt: SequelizeTestUtils.getNowWithoutTime(), - createdById: mockIRepositoryOptions.currentUser.id, - updatedById: mockIRepositoryOptions.currentUser.id, - tenantId: mockIRepositoryOptions.currentTenant.id, - options: [], - show: id.show, - type: id.type, - canDelete: id.canDelete, - name: id.name, - label: id.label, - }, - { - id: avatarUrlCreated.id, - createdAt: SequelizeTestUtils.getNowWithoutTime(), - updatedAt: SequelizeTestUtils.getNowWithoutTime(), - createdById: mockIRepositoryOptions.currentUser.id, - updatedById: mockIRepositoryOptions.currentUser.id, - tenantId: mockIRepositoryOptions.currentTenant.id, - options: [], - show: avatarUrl.show, - type: avatarUrl.type, - canDelete: avatarUrl.canDelete, - name: avatarUrl.name, - label: avatarUrl.label, - }, - { - id: urlCreated.id, - createdAt: SequelizeTestUtils.getNowWithoutTime(), - updatedAt: SequelizeTestUtils.getNowWithoutTime(), - createdById: mockIRepositoryOptions.currentUser.id, - updatedById: mockIRepositoryOptions.currentUser.id, - tenantId: mockIRepositoryOptions.currentTenant.id, - options: [], - show: url.show, - type: url.type, - canDelete: url.canDelete, - name: url.name, - label: url.label, - }, - { - id: bioCreated.id, - createdAt: SequelizeTestUtils.getNowWithoutTime(), - updatedAt: SequelizeTestUtils.getNowWithoutTime(), - createdById: mockIRepositoryOptions.currentUser.id, - updatedById: mockIRepositoryOptions.currentUser.id, - tenantId: mockIRepositoryOptions.currentTenant.id, - options: [], - show: bio.show, - type: bio.type, - canDelete: bio.canDelete, - name: bio.name, - label: bio.label, - }, - { - id: locationCreated.id, - createdAt: SequelizeTestUtils.getNowWithoutTime(), - updatedAt: SequelizeTestUtils.getNowWithoutTime(), - createdById: mockIRepositoryOptions.currentUser.id, - updatedById: mockIRepositoryOptions.currentUser.id, - tenantId: mockIRepositoryOptions.currentTenant.id, - options: [], - show: location.show, - type: location.type, - canDelete: location.canDelete, - name: location.name, - label: location.label, - }, - ] - - expect(attributes).toEqual(expected) - }) - it('Should create predefined slack attributes', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - const as = new MemberAttributeSettingsService(mockIRepositoryOptions) - - const attributes = (await as.createPredefined(SLACK_MEMBER_ATTRIBUTES)).map((attribute) => { - attribute.createdAt = (attribute.createdAt as any).toISOString().split('T')[0] - attribute.updatedAt = (attribute.updatedAt as any).toISOString().split('T')[0] - return attribute - }) - - const [idCreated, avatarUrlCreated, jobTitleCreated, timezoneCreated] = attributes - - const [id, avatarUrl, jobTitle, timezone] = SLACK_MEMBER_ATTRIBUTES - - const expected = [ - { - id: idCreated.id, - createdAt: SequelizeTestUtils.getNowWithoutTime(), - updatedAt: SequelizeTestUtils.getNowWithoutTime(), - createdById: mockIRepositoryOptions.currentUser.id, - updatedById: mockIRepositoryOptions.currentUser.id, - tenantId: mockIRepositoryOptions.currentTenant.id, - options: [], - show: id.show, - type: id.type, - canDelete: id.canDelete, - name: id.name, - label: id.label, - }, - { - id: avatarUrlCreated.id, - createdAt: SequelizeTestUtils.getNowWithoutTime(), - updatedAt: SequelizeTestUtils.getNowWithoutTime(), - createdById: mockIRepositoryOptions.currentUser.id, - updatedById: mockIRepositoryOptions.currentUser.id, - tenantId: mockIRepositoryOptions.currentTenant.id, - options: [], - show: avatarUrl.show, - type: avatarUrl.type, - canDelete: avatarUrl.canDelete, - name: avatarUrl.name, - label: avatarUrl.label, - }, - { - id: jobTitleCreated.id, - createdAt: SequelizeTestUtils.getNowWithoutTime(), - updatedAt: SequelizeTestUtils.getNowWithoutTime(), - createdById: mockIRepositoryOptions.currentUser.id, - updatedById: mockIRepositoryOptions.currentUser.id, - tenantId: mockIRepositoryOptions.currentTenant.id, - options: [], - show: jobTitle.show, - type: jobTitle.type, - canDelete: jobTitle.canDelete, - name: jobTitle.name, - label: jobTitle.label, - }, - { - id: timezoneCreated.id, - createdAt: SequelizeTestUtils.getNowWithoutTime(), - updatedAt: SequelizeTestUtils.getNowWithoutTime(), - createdById: mockIRepositoryOptions.currentUser.id, - updatedById: mockIRepositoryOptions.currentUser.id, - tenantId: mockIRepositoryOptions.currentTenant.id, - options: [], - show: timezone.show, - type: timezone.type, - canDelete: timezone.canDelete, - name: timezone.name, - label: timezone.label, - }, - ] - - expect(attributes).toEqual(expected) - }) - it('Should accept duplicate attributes from different platforms without an exception', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - const as = new MemberAttributeSettingsService(mockIRepositoryOptions) - - const attributes = await as.createPredefined(TWITTER_MEMBER_ATTRIBUTES) - - const attributes2 = (await as.createPredefined(DEVTO_MEMBER_ATTRIBUTES)).map((attribute) => { - attribute.createdAt = (attribute.createdAt as any).toISOString().split('T')[0] - attribute.updatedAt = (attribute.updatedAt as any).toISOString().split('T')[0] - return attribute - }) - - // create predefined method should still return shared attributes `url` and `id` - const [ - idCreatedTwitter, - _avatarUrlCreated, - urlCreatedTwitter, - bioCreatedTwitter, - locationCreatedTwitter, - ] = attributes - - const [ - _idCreatedDevTo, - _urlCreatedDevTo, - nameCreatedDevTo, - _bioCreatedDevTo, - _locationCreatedDevTo, - ] = attributes2 - - const [id, url, name, bio, location] = DEVTO_MEMBER_ATTRIBUTES - console.log('urlCreatedTwitter', urlCreatedTwitter.id) - console.log('urlCreatedDevTo', _urlCreatedDevTo.id) - console.log('bioCreatedTwitter', bioCreatedTwitter.id) - console.log('bioCreatedDevTo', _bioCreatedDevTo.id) - console.log('locationCreatedTwitter', locationCreatedTwitter.id) - console.log('locationCreatedDevTo', _locationCreatedDevTo.id) - const expected = [ - { - id: idCreatedTwitter.id, - createdAt: SequelizeTestUtils.getNowWithoutTime(), - updatedAt: SequelizeTestUtils.getNowWithoutTime(), - createdById: mockIRepositoryOptions.currentUser.id, - updatedById: mockIRepositoryOptions.currentUser.id, - tenantId: mockIRepositoryOptions.currentTenant.id, - options: [], - show: id.show, - type: id.type, - canDelete: id.canDelete, - name: id.name, - label: id.label, - }, - { - id: _urlCreatedDevTo.id, - createdAt: SequelizeTestUtils.getNowWithoutTime(), - updatedAt: SequelizeTestUtils.getNowWithoutTime(), - createdById: mockIRepositoryOptions.currentUser.id, - updatedById: mockIRepositoryOptions.currentUser.id, - tenantId: mockIRepositoryOptions.currentTenant.id, - options: [], - show: url.show, - type: url.type, - canDelete: url.canDelete, - name: url.name, - label: url.label, - }, - { - id: nameCreatedDevTo.id, - createdAt: SequelizeTestUtils.getNowWithoutTime(), - updatedAt: SequelizeTestUtils.getNowWithoutTime(), - createdById: mockIRepositoryOptions.currentUser.id, - updatedById: mockIRepositoryOptions.currentUser.id, - tenantId: mockIRepositoryOptions.currentTenant.id, - options: [], - show: name.show, - type: name.type, - canDelete: name.canDelete, - name: name.name, - label: name.label, - }, - { - id: _bioCreatedDevTo.id, - createdAt: SequelizeTestUtils.getNowWithoutTime(), - updatedAt: SequelizeTestUtils.getNowWithoutTime(), - createdById: mockIRepositoryOptions.currentUser.id, - updatedById: mockIRepositoryOptions.currentUser.id, - tenantId: mockIRepositoryOptions.currentTenant.id, - options: [], - show: bio.show, - type: bio.type, - canDelete: bio.canDelete, - name: bio.name, - label: bio.label, - }, - { - id: _locationCreatedDevTo.id, - createdAt: SequelizeTestUtils.getNowWithoutTime(), - updatedAt: SequelizeTestUtils.getNowWithoutTime(), - createdById: mockIRepositoryOptions.currentUser.id, - updatedById: mockIRepositoryOptions.currentUser.id, - tenantId: mockIRepositoryOptions.currentTenant.id, - options: [], - show: location.show, - type: location.type, - canDelete: location.canDelete, - name: location.name, - label: location.label, - }, - ] - - expect(attributes2).toEqual(expected) - - // find all attributes: url, name, id, imgUrl should be present - const allAttributes = await as.findAndCountAll({}) - - expect(allAttributes.count).toBe(6) - const allAttributeNames = allAttributes.rows.map((attribute) => attribute.name) - - expect(allAttributeNames).toEqual(['name', 'url', 'bio', 'location', 'avatarUrl', 'sourceId']) - }) - }) - describe('create tests', () => { - it('Should add single attribute to member attributes - all fields', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - const as = new MemberAttributeSettingsService(mockIRepositoryOptions) - - const attribute1 = { - name: 'att1', - label: 'attribute 1', - type: MemberAttributeType.BOOLEAN, - canDelete: true, - show: true, - } - - const attributeCreated = await as.create(attribute1) - - const attributeExpected = { - ...attributeCreated, - options: [], - name: attribute1.name, - label: attribute1.label, - type: attribute1.type, - canDelete: attribute1.canDelete, - show: attribute1.show, - } - - expect(attributeCreated).toStrictEqual(attributeExpected) - }) - - it('Should create a multi-select field with options', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - const as = new MemberAttributeSettingsService(mockIRepositoryOptions) - - const attribute1 = { - name: 'att1', - label: 'attribute 1', - type: MemberAttributeType.MULTI_SELECT, - options: ['option1', 'option2'], - canDelete: true, - show: true, - } - - const attributeCreated = await as.create(attribute1) - - const attributeExpected = { - ...attributeCreated, - options: ['option1', 'option2'], - name: attribute1.name, - label: attribute1.label, - type: attribute1.type, - canDelete: attribute1.canDelete, - show: attribute1.show, - } - - expect(attributeCreated).toStrictEqual(attributeExpected) - }) - - it('Should add single attribute to member attributes - without default fields', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - const as = new MemberAttributeSettingsService(mockIRepositoryOptions) - - const attribute1 = { - name: 'att1', - label: 'attribute 1', - type: MemberAttributeType.BOOLEAN, - } - - const attributeCreated = await as.create(attribute1) - - // canDelete and show should be true by default - const attributeExpected = { - ...attributeCreated, - options: [], - name: attribute1.name, - label: attribute1.label, - type: attribute1.type, - canDelete: true, - show: true, - } - - expect(attributeCreated).toStrictEqual(attributeExpected) - }) - - it('Should add single attribute to member attributes - without default fields and name', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - const as = new MemberAttributeSettingsService(mockIRepositoryOptions) - - const attribute1 = { - label: 'an attribute with multiple words', - type: MemberAttributeType.BOOLEAN, - } - - const attributeCreated = await as.create(attribute1) - - // name should be generated from the label - const attributeExpected = { - ...attributeCreated, - options: [], - name: 'anAttributeWithMultipleWords', - label: attribute1.label, - type: attribute1.type, - canDelete: true, - show: true, - } - - expect(attributeCreated).toStrictEqual(attributeExpected) - }) - }) - - describe('destroyAll tests', () => { - it('Should remove a single attribute succesfully', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - const as = new MemberAttributeSettingsService(mockIRepositoryOptions) - - const attribute = await as.create({ - name: 'att1', - label: 'attribute 1', - type: MemberAttributeType.BOOLEAN, - canDelete: true, - show: true, - }) - - await as.destroyAll([attribute.id]) - - const allAttributes = await as.findAndCountAll({}) - - expect(allAttributes.count).toBe(0) - expect(allAttributes.rows).toStrictEqual([]) - }) - - it('Should remove multiple existing attributes successfully, and should silently accept non existing names and keep the canDelete=false attributes intact', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - const as = new MemberAttributeSettingsService(mockIRepositoryOptions) - - const attribute1 = await as.create({ - name: 'att1', - label: 'attribute 1', - type: MemberAttributeType.BOOLEAN, - canDelete: true, - show: true, - }) - - const attribute2 = await as.create({ - name: 'att2', - label: 'attribute 2', - type: MemberAttributeType.STRING, - canDelete: false, - show: true, - }) - - const attribute3 = await as.create({ - name: 'att3', - label: 'attribute 3', - type: MemberAttributeType.EMAIL, - canDelete: true, - show: false, - }) - - await as.destroyAll([attribute1.id, attribute2.id, attribute3.id]) - - const allAttributes = await as.findAndCountAll({}) - - expect(allAttributes.count).toBe(1) - expect(allAttributes.rows).toStrictEqual([attribute2]) - }) - }) - - describe('update tests', () => { - it(`Should throw typesNotMatching 400 error when updating an existing attribute's type to another value`, async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - const as = new MemberAttributeSettingsService(mockIRepositoryOptions) - - const attribute = await as.create({ - name: 'attribute 1', - label: 'attribute 1', - type: MemberAttributeType.BOOLEAN, - canDelete: true, - show: true, - }) - - await expect(() => - as.update(attribute.id, { - name: attribute.name, - label: 'some other label', - type: MemberAttributeType.STRING, - }), - ).rejects.toThrowError( - new Error400('en', 'settings.memberAttributes.errors.typesNotMatching', attribute.name), - ) - }) - - it(`Should throw canDeleteReadonly 400 error when updating an existing attribute's canDelete field to another value`, async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - const as = new MemberAttributeSettingsService(mockIRepositoryOptions) - - const attribute = await as.create({ - name: 'attribute 1', - label: 'attribute 1', - type: MemberAttributeType.BOOLEAN, - canDelete: true, - show: true, - }) - - await expect(() => - as.update(attribute.id, { - canDelete: false, - show: true, - }), - ).rejects.toThrowError( - new Error400('en', 'settings.memberAttributes.errors.canDeleteReadonly', attribute.name), - ) - }) - - it(`Should should update other cases successfully`, async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - const as = new MemberAttributeSettingsService(mockIRepositoryOptions) - - const attribute = await as.create({ - name: 'attribute 1', - label: 'attribute 1', - type: MemberAttributeType.BOOLEAN, - canDelete: true, - show: true, - }) - - const attribute1Update = { - name: attribute.name, - label: 'some other label', - type: attribute.type, - canDelete: true, - show: false, - } - - const updatedAttribute = await as.update(attribute.id, attribute1Update) - - const expectedAttribute = { - ...updatedAttribute, - name: attribute.name, - label: attribute1Update.label, - type: attribute.type, - canDelete: attribute.canDelete, - show: attribute1Update.show, - } - - expect(updatedAttribute).toStrictEqual(expectedAttribute) - }) - }) - - describe('isCorrectType tests', () => { - it(`Should check various types and values successfully`, async () => { - const isCorrectType = MemberAttributeSettingsService.isCorrectType - - // boolean - expect(isCorrectType(true, MemberAttributeType.BOOLEAN)).toBeTruthy() - expect(isCorrectType(false, MemberAttributeType.BOOLEAN)).toBeTruthy() - expect(isCorrectType('true', MemberAttributeType.BOOLEAN)).toBeTruthy() - expect(isCorrectType('false', MemberAttributeType.BOOLEAN)).toBeTruthy() - - expect(isCorrectType(5, MemberAttributeType.BOOLEAN)).toBeFalsy() - expect(isCorrectType('someString', MemberAttributeType.BOOLEAN)).toBeFalsy() - expect(isCorrectType({}, MemberAttributeType.BOOLEAN)).toBeFalsy() - expect(isCorrectType([], MemberAttributeType.BOOLEAN)).toBeFalsy() - - // string - expect(isCorrectType('', MemberAttributeType.STRING)).toBeTruthy() - expect(isCorrectType('someString', MemberAttributeType.STRING)).toBeTruthy() - - expect(isCorrectType(5, MemberAttributeType.STRING)).toBeFalsy() - expect(isCorrectType(true, MemberAttributeType.STRING)).toBeFalsy() - expect(isCorrectType({}, MemberAttributeType.STRING)).toBeFalsy() - - // date - expect(isCorrectType('2022-05-10', MemberAttributeType.DATE)).toBeTruthy() - expect(isCorrectType('2022-06-15T00:00:00', MemberAttributeType.DATE)).toBeTruthy() - expect(isCorrectType('2022-07-14T00:00:00Z', MemberAttributeType.DATE)).toBeTruthy() - - expect(isCorrectType(5, MemberAttributeType.DATE)).toBeFalsy() - expect(isCorrectType('someString', MemberAttributeType.DATE)).toBeFalsy() - expect(isCorrectType('', MemberAttributeType.DATE)).toBeFalsy() - expect(isCorrectType(true, MemberAttributeType.DATE)).toBeFalsy() - expect(isCorrectType({}, MemberAttributeType.DATE)).toBeFalsy() - expect(isCorrectType([], MemberAttributeType.DATE)).toBeFalsy() - - // email - expect(isCorrectType('anil@crowd.dev', MemberAttributeType.EMAIL)).toBeTruthy() - expect(isCorrectType('anil+123@crowd.dev', MemberAttributeType.EMAIL)).toBeTruthy() - - expect(isCorrectType(15, MemberAttributeType.EMAIL)).toBeFalsy() - expect(isCorrectType('', MemberAttributeType.EMAIL)).toBeFalsy() - expect(isCorrectType('someString', MemberAttributeType.EMAIL)).toBeFalsy() - expect(isCorrectType(true, MemberAttributeType.EMAIL)).toBeFalsy() - expect(isCorrectType({}, MemberAttributeType.EMAIL)).toBeFalsy() - expect(isCorrectType([], MemberAttributeType.EMAIL)).toBeFalsy() - - // number - expect(isCorrectType(100, MemberAttributeType.NUMBER)).toBeTruthy() - expect(isCorrectType(5.123, MemberAttributeType.NUMBER)).toBeTruthy() - expect(isCorrectType(0.000001, MemberAttributeType.NUMBER)).toBeTruthy() - expect(isCorrectType(0, MemberAttributeType.NUMBER)).toBeTruthy() - expect(isCorrectType('125', MemberAttributeType.NUMBER)).toBeTruthy() - - expect(isCorrectType('', MemberAttributeType.NUMBER)).toBeFalsy() - expect(isCorrectType('someString', MemberAttributeType.NUMBER)).toBeFalsy() - expect(isCorrectType(true, MemberAttributeType.NUMBER)).toBeFalsy() - expect(isCorrectType({}, MemberAttributeType.NUMBER)).toBeFalsy() - expect(isCorrectType([], MemberAttributeType.NUMBER)).toBeFalsy() - - // multiselect - expect( - isCorrectType(['a', 'b', 'c'], MemberAttributeType.MULTI_SELECT, { - options: ['a', 'b', 'c', 'd'], - }), - ).toBeTruthy() - expect( - isCorrectType([], MemberAttributeType.MULTI_SELECT, { options: ['a', 'b', 'c', 'd'] }), - ).toBeTruthy() - expect( - isCorrectType(['a'], MemberAttributeType.MULTI_SELECT, { options: ['a', 'b', 'c', 'd'] }), - ).toBeTruthy() - expect( - isCorrectType(['a', '42'], MemberAttributeType.MULTI_SELECT, { - options: ['a', 'b', 'c', 'd'], - }), - ).toBeFalsy() - expect( - isCorrectType('a', MemberAttributeType.MULTI_SELECT, { options: ['a', 'b', 'c'] }), - ).toBeFalsy() - expect( - isCorrectType(5, MemberAttributeType.MULTI_SELECT, { options: ['a', 'b', 'c'] }), - ).toBeFalsy() - }) - }) -}) diff --git a/backend/src/services/__tests__/microserviceService.test.ts b/backend/src/services/__tests__/microserviceService.test.ts deleted file mode 100644 index 157159f252..0000000000 --- a/backend/src/services/__tests__/microserviceService.test.ts +++ /dev/null @@ -1,84 +0,0 @@ -import SequelizeTestUtils from '../../database/utils/sequelizeTestUtils' -import MicroserviceService from '../microserviceService' - -const db = null - -describe('MicroService Service tests', () => { - beforeEach(async () => { - await SequelizeTestUtils.wipeDatabase(db) - }) - - afterAll((done) => { - // Closing the DB connection allows Jest to exit successfully. - SequelizeTestUtils.closeConnection(db) - done() - }) - - describe('CreateIfNotExists method', () => { - it('Should create a microservice succesfully with default values', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - - const microservice2Add = { type: 'members_score' } - - const microserviceCreated = await new MicroserviceService( - mockIRepositoryOptions, - ).createIfNotExists(microservice2Add) - - microserviceCreated.createdAt = microserviceCreated.createdAt.toISOString().split('T')[0] - microserviceCreated.updatedAt = microserviceCreated.updatedAt.toISOString().split('T')[0] - - const microserviceExpected = { - id: microserviceCreated.id, - init: false, - running: false, - type: microservice2Add.type, - variant: 'default', - settings: {}, - importHash: null, - createdAt: SequelizeTestUtils.getNowWithoutTime(), - updatedAt: SequelizeTestUtils.getNowWithoutTime(), - tenantId: mockIRepositoryOptions.currentTenant.id, - createdById: mockIRepositoryOptions.currentUser.id, - updatedById: mockIRepositoryOptions.currentUser.id, - } - - expect(microserviceCreated).toStrictEqual(microserviceExpected) - }) - it('Should return the existing if it does not exist', async () => { - const mockIRepositoryOptions = await SequelizeTestUtils.getTestIRepositoryOptions(db) - - const microservice2Add = { type: 'members_score' } - - const microserviceCreated = await new MicroserviceService(mockIRepositoryOptions).create( - microservice2Add, - ) - - const secondCreated = await new MicroserviceService(mockIRepositoryOptions).createIfNotExists( - microservice2Add, - ) - - secondCreated.createdAt = secondCreated.createdAt.toISOString().split('T')[0] - secondCreated.updatedAt = secondCreated.updatedAt.toISOString().split('T')[0] - - const microserviceExpected = { - id: microserviceCreated.id, - init: false, - running: false, - type: microservice2Add.type, - variant: 'default', - settings: {}, - importHash: null, - createdAt: SequelizeTestUtils.getNowWithoutTime(), - updatedAt: SequelizeTestUtils.getNowWithoutTime(), - tenantId: mockIRepositoryOptions.currentTenant.id, - createdById: mockIRepositoryOptions.currentUser.id, - updatedById: mockIRepositoryOptions.currentUser.id, - } - - expect(secondCreated).toStrictEqual(microserviceExpected) - const count = (await new MicroserviceService(mockIRepositoryOptions).findAndCountAll({})) - .count - expect(count).toBe(1) - }) - }) -}) diff --git a/backend/src/services/__tests__/tenantService.test.ts b/backend/src/services/__tests__/tenantService.test.ts deleted file mode 100644 index 1d8d60aa54..0000000000 --- a/backend/src/services/__tests__/tenantService.test.ts +++ /dev/null @@ -1,119 +0,0 @@ -import { getRedisClient } from '@crowd/redis' -import { MemberAttributeName } from '@crowd/types' - -import { REDIS_CONFIG } from '../../conf' -import SequelizeTestUtils from '../../database/utils/sequelizeTestUtils' -import { IServiceOptions } from '../IServiceOptions' -import MemberAttributeSettingsService from '../memberAttributeSettingsService' -import MicroserviceService from '../microserviceService' -import TenantService from '../tenantService' - -const db = null - -describe('TenantService tests', () => { - beforeEach(async () => { - await SequelizeTestUtils.wipeDatabase(db) - }) - - afterAll(async () => { - // Closing the DB connection allows Jest to exit successfully. - await SequelizeTestUtils.closeConnection(db) - }) - - describe('_findAndCountAllForEveryUser method', () => { - it('Should succesfully find all tenants without filtering by currentUser', async () => { - let tenants = await TenantService._findAndCountAllForEveryUser({ filter: {} }) - - expect(tenants.count).toEqual(0) - expect(tenants.rows).toEqual([]) - - // generate 3 tenants - const mockIServiceOptions1 = await SequelizeTestUtils.getTestIServiceOptions(db) - const mockIServiceOptions2 = await SequelizeTestUtils.getTestIServiceOptions(db) - const mockIServiceOptions3 = await SequelizeTestUtils.getTestIServiceOptions(db) - - tenants = await TenantService._findAndCountAllForEveryUser({ filter: {} }) - - expect(tenants.count).toEqual(3) - expect(tenants.rows.map((i) => i.id).sort()).toEqual( - [ - mockIServiceOptions1.currentTenant.id, - mockIServiceOptions2.currentTenant.id, - mockIServiceOptions3.currentTenant.id, - ].sort(), - ) - }) - }) - - describe('create method', () => { - it('Should succesfully create the tenant, related default microservices, and settings', async () => { - const randomUser = await SequelizeTestUtils.getRandomUser() - let db = null - db = await SequelizeTestUtils.getDatabase(db) - - const userModel = await db.user.create(randomUser) - // Get options without currentTenant - const options = { - language: 'en', - currentUser: userModel, - database: db, - redis: await getRedisClient(REDIS_CONFIG, true), - } as IServiceOptions - - const tenantCreated = await new TenantService(options).create({ - name: 'testName', - url: 'testUrl', - integrationsRequired: ['github', 'discord'], - communitySize: '>25000', - }) - - const tenantCreatedPlain = tenantCreated.get({ plain: true }) - - tenantCreatedPlain.createdAt = tenantCreatedPlain.createdAt.toISOString().split('T')[0] - tenantCreatedPlain.updatedAt = tenantCreatedPlain.updatedAt.toISOString().split('T')[0] - - const tenantExpected = { - id: tenantCreatedPlain.id, - name: 'testName', - url: 'testUrl', - onboardedAt: null, - integrationsRequired: ['github', 'discord'], - communitySize: '>25000', - createdAt: SequelizeTestUtils.getNowWithoutTime(), - updatedAt: SequelizeTestUtils.getNowWithoutTime(), - deletedAt: null, - createdById: options.currentUser.id, - updatedById: options.currentUser.id, - settings: [], - conversationSettings: [], - reasonForUsingCrowd: null, - } - - expect(tenantCreatedPlain).toStrictEqual(tenantExpected) - - // Check microservices (members_score should be created with tenantService.create) - const ms = new MicroserviceService({ ...options, currentTenant: tenantCreated }) - const microservicesOfTenant = await ms.findAndCountAll({}) - - expect(microservicesOfTenant.count).toEqual(1) - - // findAndCountAll returns sorted by createdAt (desc) by default, so first one should be members_score - expect(microservicesOfTenant.rows[0].type).toEqual('members_score') - - // Check default member attributes - const mas = new MemberAttributeSettingsService({ ...options, currentTenant: tenantCreated }) - const defaultAttributes = await mas.findAndCountAll({ filter: {} }) - - expect(defaultAttributes.rows.map((i) => i.name).sort()).toEqual([ - MemberAttributeName.BIO, - MemberAttributeName.COMPANY, - MemberAttributeName.IS_BOT, - MemberAttributeName.IS_ORGANIZATION, - MemberAttributeName.IS_TEAM_MEMBER, - MemberAttributeName.JOB_TITLE, - MemberAttributeName.LOCATION, - MemberAttributeName.URL, - ]) - }) - }) -}) diff --git a/backend/src/services/__tests__/test-sample-data.json b/backend/src/services/__tests__/test-sample-data.json deleted file mode 100644 index e2657978c3..0000000000 --- a/backend/src/services/__tests__/test-sample-data.json +++ /dev/null @@ -1,286 +0,0 @@ -[ - { - "username": { "discord": "considerate snewkes" }, - "type": "member", - "info": {}, - "attributes": { - "url": { "github": "https://github.com/CrowdHQ" }, - "name": { "github": "considerate snewkes" }, - "isHireable": { "github": false }, - "websiteUrl": { "github": "https://crowd.dev" }, - "sourceId": { "discord": "#sample-discord-id" } - }, - "email": "team@crowd.dev", - "score": 10, - "bio": "Member of the @vuejs core team, hobby frontend hacker. Not a dev by profession.", - "organisation": "crowd.dev", - "location": "Mannheim, Germany", - "signals": null, - "joinedAt": "2021-08-18T17:47:52.000Z", - "importHash": null, - "tagsArray": [null], - "activities": [ - { - "type": "joined_guild", - "timestamp": "2022-03-16T21:00:01.000Z", - "platform": "discord", - "info": {}, - "attributes": {}, - "isContribution": false, - "score": 2, - "sourceId": "#sourceId1" - }, - { - "type": "message", - "timestamp": "2022-03-11T21:00:00.000Z", - "platform": "discord", - "info": {}, - "attributes": { "thread": false, "reactions": [], "attachments": [] }, - "isContribution": true, - "score": 1, - "sourceId": "#sourceId2", - "url": "", - "body": "Laboris cillum aliquip cupidatat dolor nisi culpa. Occaecat fugiat sunt anim.", - "channel": "introductions" - } - ], - "reach": { "total": -1 }, - "tags": [], - "noMerge": [], - "toMerge": [] - }, - { - "username": { "github": "amazing worshipper", "discord": "amazing worshipper" }, - "type": "member", - "info": {}, - "attributes": { - "url": { "github": "https://github.com/CrowdHQ" }, - "name": { "github": "amazing worshipper" }, - "isHireable": { "github": true }, - "websiteUrl": { "github": "https://crowd.dev" }, - "sourceId": { "discord": "#sample-discord-id" } - }, - "email": "team@crowd.dev", - "score": 10, - "bio": "Javascript developer. I love Vue!", - "organisation": "crowd.dev", - "location": "Brazil", - "signals": null, - "joinedAt": "2022-01-05T14:40:47.000Z", - "importHash": null, - "tagsArray": [null], - "activities": [ - { - "type": "pull_request-comment", - "timestamp": "2022-01-14T22:30:03.000Z", - "platform": "github", - "info": {}, - "attributes": { "parent_url": "https://github.com/vuejs/core/pull/5228" }, - "isContribution": true, - "score": 3, - "sourceId": "#sourceId3", - "importHash": null, - "parentId": null, - "url": "https://github.com/vuejs/core/pull/5228#issuecomment-1013516865", - "body": "yes, I have some .native listeners, not sure how many, but I'll definitely search all places and go with your suggestion, thanks again, and sorry for the coffee joke, it wasn't my intention to \"buy\" a position in the queue, but to say how important this fix is for me :)", - "title": "fix(compat): ensure fallthrough *Native events are not dropped during props update (fix #5222)", - "channel": "https://github.com/vuejs/core" - }, - { - "type": "issue-comment", - "timestamp": "2022-01-07T21:59:37.000Z", - "platform": "github", - "info": {}, - "attributes": { "parent_url": "https://github.com/vuejs/core/issues/5222" }, - "isContribution": true, - "score": 3, - "sourceId": "#sourceId4", - "importHash": null, - "parentId": null, - "url": "https://github.com/vuejs/core/issues/5222#issuecomment-1007770056", - "body": "here you go: https://github.com/oswaldofreitas/vue-compat-issue", - "title": "@click.native works only first time", - "channel": "https://github.com/vuejs/core" - }, - { - "type": "issue-comment", - "timestamp": "2022-01-07T21:53:15.000Z", - "platform": "github", - "info": {}, - "attributes": { "parent_url": "https://github.com/vuejs/core/issues/5222" }, - "isContribution": true, - "score": 3, - "sourceId": "#sourceId5", - "importHash": null, - "parentId": null, - "url": "https://github.com/vuejs/core/issues/5222#issuecomment-1007766386", - "body": "sure, I can do it. I used that service since it's one of the suggested in the Vue 3 official docs and it was really hard to find one that I could setup the vue compat plugin. I'll create a repo for it now and share as soon as I get it.\nBefore sharing that link here I tested in incognito and it worked for me (without registering), you can click in the play button to run and in the \"Show files\" to see the code", - "title": "@click.native works only first time", - "channel": "https://github.com/vuejs/core" - }, - { - "type": "issues-closed", - "timestamp": "2022-01-07T20:33:21.000Z", - "platform": "github", - "info": {}, - "attributes": { "state": "closed" }, - "isContribution": true, - "score": 4, - "sourceId": "#sourceId6", - "importHash": null, - "parentId": null, - "url": "https://github.com/vuejs/core/issues/5222", - "body": "Version\n3.2.26\nReproduction link\nreplit.com\nSteps to reproduce\n\nclick in the dropdown\nselect an item\nclick in the dropdown again\n\nWhat is expected?\nthe dropdown should open again in the 2nd time\nWhat is actually happening?\nthe dropdown doesn't open\n\nWhen the input event is emitted from the form-dropdown component the event listener for the click event doesn't work anymore. I suppose it's a bug with the vue compat handling the .native modifier", - "title": "@click.native works only first time", - "channel": "https://github.com/vuejs/core" - }, - { - "type": "issue-comment", - "timestamp": "2022-01-05T15:01:11.000Z", - "platform": "github", - "info": {}, - "attributes": { "parent_url": "https://github.com/vuejs/core/issues/5210" }, - "isContribution": true, - "score": 3, - "sourceId": "#sourceId7", - "importHash": null, - "parentId": null, - "url": "https://github.com/vuejs/core/issues/5210#issuecomment-1005761356", - "body": "oh I see, you're right! Thank you", - "title": "Wrong detecting missing v-if in named slot template", - "channel": "https://github.com/vuejs/core" - }, - { - "type": "issues-closed", - "timestamp": "2022-01-05T14:40:47.100Z", - "platform": "github", - "info": {}, - "attributes": { "state": "closed" }, - "isContribution": true, - "score": 4, - "sourceId": "#sourceId8", - "importHash": null, - "parentId": null, - "url": "https://github.com/vuejs/core/issues/5210", - "body": "Version\n3.2.26\nReproduction link\nsfc.vuejs.org/\nSteps to reproduce\nIn the reproduction link there is this code:\n

H1

\n \n\nwhich is working, but if you add a v-else to the template tag it breaks\nWhat is expected?\n