diff --git a/packages/api/test/resolvers/integrations.test.ts b/packages/api/test/resolvers/integrations.test.ts deleted file mode 100644 index a8278b06c..000000000 --- a/packages/api/test/resolvers/integrations.test.ts +++ /dev/null @@ -1,477 +0,0 @@ -import chai, { expect } from 'chai' -import 'mocha' -import nock from 'nock' -import sinonChai from 'sinon-chai' -import { Integration } from '../../src/entity/integration' -import { User } from '../../src/entity/user' -import { SetIntegrationErrorCode } from '../../src/generated/graphql' -import { - deleteIntegrations, - findIntegration, - saveIntegration, - updateIntegration, -} from '../../src/services/integrations' -import { deleteUser } from '../../src/services/user' -import { createTestUser } from '../db' -import { generateFakeUuid, graphqlRequest, request } from '../util' - -chai.use(sinonChai) - -describe('Integrations resolvers', () => { - const READWISE_API_URL = 'https://readwise.io/api/v2' - - let loginUser: User - let authToken: string - - before(async () => { - // create test user and login - loginUser = await createTestUser('loginUser') - const res = await request - .post('/local/debug/fake-user-login') - .send({ fakeEmail: loginUser.email }) - - authToken = res.body.authToken as string - }) - - after(async () => { - await deleteUser(loginUser.id) - }) - - describe('setIntegration API', () => { - const validToken = 'valid-token' - const query = ` - mutation SetIntegration($input: SetIntegrationInput!) { - setIntegration(input: $input) { - ... on SetIntegrationSuccess { - integration { - id - enabled - } - } - ... on SetIntegrationError { - errorCodes - } - } - } - ` - let integrationId: string - let token: string - let integrationName: string - let enabled: boolean - let scope: nock.Scope - - // mock Readwise Auth API - before(() => { - scope = nock(READWISE_API_URL, { - reqheaders: { Authorization: `Token ${validToken}` }, - }) - .get('/auth') - .reply(204) - .persist() - integrationName = 'READWISE' - enabled = true - token = 'test token' - }) - - after(() => { - scope.persist(false) - }) - - context('when id is not in the request', () => { - before(() => { - integrationId = '' - }) - - context('when token is invalid', () => { - before(() => { - token = 'invalid token' - nock(READWISE_API_URL, { - reqheaders: { Authorization: `Token ${token}` }, - }) - .get('/auth') - .reply(401) - }) - - it('returns InvalidToken error code', async () => { - const res = await graphqlRequest(query, authToken, { - input: { - id: integrationId, - name: integrationName, - token, - enabled, - }, - }) - expect(res.body.data.setIntegration.errorCodes).to.eql([ - SetIntegrationErrorCode.InvalidToken, - ]) - }) - }) - - context('when token is valid', () => { - before(() => { - token = validToken - }) - - afterEach(async () => { - await deleteIntegrations(loginUser.id, { - user: { id: loginUser.id }, - name: integrationName, - }) - }) - - it('creates new integration', async () => { - const res = await graphqlRequest(query, authToken, { - input: { - id: integrationId, - name: integrationName, - token, - enabled, - }, - }) - expect(res.body.data.setIntegration.integration.enabled).to.be.true - }) - }) - }) - - context('when id is in the request', () => { - let existingIntegration: Integration - - context('when integration does not exist', () => { - before(() => { - integrationId = generateFakeUuid() - }) - - it('returns NotFound error code', async () => { - const res = await graphqlRequest(query, authToken, { - input: { id: integrationId, name: integrationName, enabled, token }, - }) - expect(res.body.data.setIntegration.errorCodes).to.eql([ - SetIntegrationErrorCode.NotFound, - ]) - }) - }) - - context('when integration exists', () => { - context('when integration does not belong to the user', () => { - let otherUser: User - - before(async () => { - otherUser = await createTestUser('otherUser') - existingIntegration = await saveIntegration( - { - user: { id: otherUser.id }, - name: 'READWISE', - token: 'fakeToken', - enabled, - }, - otherUser.id - ) - integrationId = existingIntegration.id - }) - - after(async () => { - await deleteUser(otherUser.id) - await deleteIntegrations(otherUser.id, [existingIntegration.id]) - }) - - it('returns Unauthorized error code', async () => { - const res = await graphqlRequest(query, authToken, { - input: { - id: integrationId, - name: integrationName, - enabled, - token, - }, - }) - expect(res.body.data.setIntegration.errorCodes).to.eql([ - SetIntegrationErrorCode.NotFound, - ]) - }) - }) - - context('when integration belongs to the user', () => { - before(async () => { - existingIntegration = await saveIntegration( - { - user: { id: loginUser.id }, - name: 'READWISE', - token: 'fakeToken', - enabled, - }, - loginUser.id - ) - integrationId = existingIntegration.id - }) - - after(async () => { - await deleteIntegrations(loginUser.id, [existingIntegration.id]) - }) - - context('when enable is false', () => { - before(() => { - enabled = false - }) - - afterEach(async () => { - await updateIntegration( - existingIntegration.id, - { - taskName: 'some task name', - enabled: true, - }, - loginUser.id - ) - }) - - it('disables integration', async () => { - const res = await graphqlRequest(query, authToken, { - input: { - id: integrationId, - name: integrationName, - token, - enabled, - }, - }) - expect(res.body.data.setIntegration.integration.enabled).to.be - .false - }) - }) - - context('when enable is true', () => { - before(() => { - enabled = true - }) - - afterEach(async () => { - await updateIntegration( - existingIntegration.id, - { - taskName: null, - enabled: false, - }, - loginUser.id - ) - }) - - it('enables integration', async () => { - const res = await graphqlRequest(query, authToken, { - input: { - id: integrationId, - name: integrationName, - token, - enabled, - }, - }) - expect(res.body.data.setIntegration.integration.enabled).to.be - .true - }) - }) - }) - }) - }) - }) - - describe('integrations API', () => { - const query = ` - query { - integrations { - ... on IntegrationsSuccess { - integrations { - id - type - enabled - } - } - } - } - ` - - let existingIntegration: Integration - - before(async () => { - existingIntegration = await saveIntegration( - { - user: { id: loginUser.id }, - name: 'READWISE', - token: 'fakeToken', - }, - loginUser.id - ) - }) - - after(async () => { - await deleteIntegrations(loginUser.id, [existingIntegration.id]) - }) - - it('returns all integrations', async () => { - const res = await graphqlRequest(query, authToken) - expect(res.body.data.integrations.integrations).to.have.length(1) - expect(res.body.data.integrations.integrations[0].id).to.equal( - existingIntegration.id - ) - expect(res.body.data.integrations.integrations[0].type).to.equal( - existingIntegration.type - ) - expect(res.body.data.integrations.integrations[0].enabled).to.equal( - existingIntegration.enabled - ) - }) - }) - - describe('deleteIntegration API', () => { - const query = (id: string) => ` - mutation { - deleteIntegration(id: "${id}") { - ... on DeleteIntegrationSuccess { - integration { - id - } - } - ... on DeleteIntegrationError { - errorCodes - } - } - } - ` - - context('when integration exists', () => { - let existingIntegration: Integration - - beforeEach(async () => { - existingIntegration = await saveIntegration( - { - user: { id: loginUser.id }, - name: 'READWISE', - token: 'fakeToken', - taskName: 'some task name', - }, - loginUser.id - ) - }) - - it('deletes the integration and cloud task', async () => { - const res = await graphqlRequest( - query(existingIntegration.id), - authToken - ) - const integration = await findIntegration( - { - id: existingIntegration.id, - }, - loginUser.id - ) - - expect(res.body.data.deleteIntegration.integration).to.be.an('object') - expect(res.body.data.deleteIntegration.integration.id).to.eql( - existingIntegration.id - ) - expect(integration).to.be.null - }) - }) - }) - - describe('importFromIntegration API', () => { - const query = (integrationId: string) => ` - mutation { - importFromIntegration(integrationId: "${integrationId}") { - ... on ImportFromIntegrationSuccess { - success - } - ... on ImportFromIntegrationError { - errorCodes - } - } - } - ` - let existingIntegration: Integration - - context('when integration exists', () => { - before(async () => { - existingIntegration = await saveIntegration( - { - user: { id: loginUser.id }, - name: 'POCKET', - token: 'fakeToken', - }, - loginUser.id - ) - }) - - after(async () => { - await deleteIntegrations(loginUser.id, [existingIntegration.id]) - }) - - it('returns success and starts cloud task', async () => { - const res = await graphqlRequest( - query(existingIntegration.id), - authToken - ).expect(200) - expect(res.body.data.importFromIntegration.success).to.be.true - }) - }) - - context('when integration does not exist', () => { - it('returns error', async () => { - const invalidIntegrationId = generateFakeUuid() - const res = await graphqlRequest( - query(invalidIntegrationId), - authToken - ).expect(200) - expect(res.body.data.importFromIntegration.errorCodes).to.eql([ - 'UNAUTHORIZED', - ]) - }) - }) - }) - - describe('integration API', () => { - const query = ` - query Integration ($name: String!) { - integration(name: $name) { - ... on IntegrationSuccess { - integration { - id - type - enabled - } - } - ... on IntegrationError { - errorCodes - } - } - } - ` - - let existingIntegration: Integration - - before(async () => { - existingIntegration = await saveIntegration( - { - user: { id: loginUser.id }, - name: 'READWISE', - token: 'fakeToken', - }, - loginUser.id - ) - }) - - after(async () => { - await deleteIntegrations(loginUser.id, [existingIntegration.id]) - }) - - it('returns the integration', async () => { - const res = await graphqlRequest(query, authToken, { - name: existingIntegration.name, - }) - expect(res.body.data.integration.integration.id).to.equal( - existingIntegration.id - ) - expect(res.body.data.integration.integration.type).to.equal( - existingIntegration.type - ) - expect(res.body.data.integration.integration.enabled).to.equal( - existingIntegration.enabled - ) - }) - }) -})