huridocs/uwazi

View on GitHub
app/api/search/specs/entitiesIndex.spec.ts

Summary

Maintainability
A
0 mins
Test Coverage
import { legacyLogger } from 'api/log';
import { elasticTesting } from 'api/utils/elastic_testing';
import { UserInContextMockFactory } from 'api/utils/testingUserInContext';
import db from 'api/utils/testing_db';
import { AccessLevels, PermissionType } from 'shared/types/permissionSchema';
import { UserRole } from 'shared/types/userSchema';
import { elastic } from '../elastic';
import { reindexAll, updateMapping } from '../entitiesIndex';
import { search } from '../search';
import { fixtures as fixturesForIndexErrors } from './fixtures_elastic_errors';

const forceIndexingOfNumberBasedProperty = async () => {
  await search.indexEntities({ title: 'Entity with index Problems 1' }, '', 1);
};

describe('entitiesIndex', () => {
  const elasticIndex = 'index_for_entities_index_testing';
  const userFactory = new UserInContextMockFactory();

  beforeEach(async () => {
    await db.setupFixturesAndContext({}, elasticIndex);
  });

  afterAll(async () => {
    await db.disconnect();
  });

  describe('indexEntities', () => {
    const loadFailingFixtures = async () => {
      await db.setupFixturesAndContext(fixturesForIndexErrors);
      await elasticTesting.resetIndex();
      // force indexing will ensure that all exceptions are mapper_parsing. Otherwise you get different kinds of exceptions
      await forceIndexingOfNumberBasedProperty();
      await elasticTesting.refresh();
    };

    it('indexing without errors', async () => {
      jest.spyOn(legacyLogger, 'error').mockImplementation(() => {});
      await loadFailingFixtures();
      await search.indexEntities({ title: 'Entity with index Problems 1' }, '', 1);
      expect(legacyLogger.error).not.toHaveBeenCalled();
      await elasticTesting.refresh();
      const indexedEntities = await search.search({}, 'en');
      expect(indexedEntities.rows.length).toBe(1);
    });
  });

  describe('indexEntities by query', () => {
    it('should only index the entities that match the query', async () => {
      await db.setupFixturesAndContext({
        entities: [
          { title: 'title1', language: 'en' },
          { title: 'titulo1', language: 'es' },
          { title: 'title2', language: 'en' },
          { title: 'titulo2', language: 'es' },
          { title: 'title3', language: 'en' },
          { title: 'titulo3', language: 'es' },
          { title: 'title4', language: 'en' },
          { title: 'titulo4', language: 'es' },
          { title: 'title5', language: 'en' },
          {
            title: 'titulo5',
            language: 'es',
            permissions: [{ refId: 'user1', type: PermissionType.USER, level: AccessLevels.WRITE }],
          },
        ],
      });

      await search.indexEntities({ language: 'es' }, '', 2);
      await elasticTesting.refresh();

      const indexedEntities = await elasticTesting.getIndexedEntities();

      expect(indexedEntities).toEqual([
        expect.objectContaining({ title: 'titulo1' }),
        expect.objectContaining({ title: 'titulo2' }),
        expect.objectContaining({ title: 'titulo3' }),
        expect.objectContaining({ title: 'titulo4' }),
        expect.objectContaining({
          title: 'titulo5',
          permissions: [{ refId: 'user1', type: PermissionType.USER, level: AccessLevels.WRITE }],
        }),
      ]);
    });
  });

  describe('updateMapping', () => {
    it('should update the mapping provided by the factory', async () => {
      const template = {
        _id: '123',
        name: 'test',
        properties: [
          { _id: '123', name: 'name', type: 'text' },
          { name: 'dob', type: 'date' },
          { name: 'country', type: 'select' },
        ],
      };
      await updateMapping([template]);
      const mapping = await elastic.indices.getMapping();
      const mappedProps = mapping.body[elasticIndex].mappings.properties.metadata.properties;
      expect(mappedProps.name).toMatchSnapshot();
      expect(mappedProps.dob).toMatchSnapshot();
      expect(mappedProps.country).toMatchSnapshot();
    });
  });

  describe('reindexAll', () => {
    it('should reindex the entities', async () => {
      const entities = [
        { title: 'title1', language: 'en' },
        { title: 'titulo1', language: 'es' },
        { title: 'title2', language: 'en' },
        { title: 'titulo2', language: 'es' },
      ];

      await db.setupFixturesAndContext({ entities });
      userFactory.mock({
        _id: 'user1',
        username: 'collaborator',
        role: UserRole.COLLABORATOR,
        email: 'col@test.com',
      });

      await search.indexEntities({});
      await elasticTesting.refresh();

      await reindexAll([], search);
      await elasticTesting.refresh();

      expect(await elasticTesting.getIndexedEntities('')).toEqual([
        expect.objectContaining({ title: 'title1' }),
        expect.objectContaining({ title: 'titulo1' }),
        expect.objectContaining({ title: 'title2' }),
        expect.objectContaining({ title: 'titulo2' }),
      ]);
    });

    it('should delete a field from the mapping', async () => {
      const templateA = {
        _id: '123',
        name: 'template A',
        properties: [
          { name: 'name', type: 'text' },
          { name: 'dob', type: 'date' },
          { name: 'country', type: 'select' },
        ],
      };

      await updateMapping([templateA]);
      templateA.properties = [
        { name: 'name', type: 'text' },
        { name: 'country', type: 'select' },
      ];
      await reindexAll([templateA], search);
      const mapping = await elastic.indices.getMapping();

      expect(
        mapping.body[elasticIndex].mappings.properties.metadata.properties.dob
      ).toBeUndefined();
    });
  });
});