huridocs/uwazi

View on GitHub
app/react/Metadata/components/specs/MetadataForm.spec.js

Summary

Maintainability
A
0 mins
Test Coverage
/** @format */

import React from 'react';
import { shallow } from 'enzyme';
import Immutable from 'immutable';
import { Form, Field } from 'react-redux-form';

import { MetadataForm, mapStateToProps } from '../MetadataForm';
import MetadataFormFields from '../MetadataFormFields';
import { Select as SimpleSelect } from '../../../Forms';
import { SupportingFiles } from '../SupportingFiles';

describe('MetadataForm', () => {
  let component;
  let fieldsTemplate;
  let props;
  let templates;

  beforeEach(() => {
    fieldsTemplate = [
      { name: 'field1', label: 'label1' },
      { name: 'field2', label: 'label2', type: 'select', content: '2' },
      { name: 'field3', label: 'label3', type: 'multiselect', content: '2' },
      { name: 'field4', label: 'label4', type: 'date' },
    ];

    templates = Immutable.fromJS([
      {
        name: 'template1',
        _id: 'templateId',
        properties: fieldsTemplate,
        commonProperties: [{ name: 'title', label: 'Title' }],
      },
      {
        name: 'template2',
        _id: '2',
        properties: [{ name: 'field3' }],
        commonProperties: [{ name: 'title', label: 'Title' }],
        isEntity: false,
      },
      {
        name: 'template3',
        _id: '3',
        properties: [{ name: 'field4' }],
        commonProperties: [{ name: 'title', label: 'Title' }],
        isEntity: true,
      },
    ]);

    props = {
      metadata: {
        _id: [{ value: 'docId' }],
        template: [{ value: 'templateId' }],
        title: [{ value: 'testTitle' }],
        metadata: [{ value: { field1: 'field1value', field2: 'field2value' } }],
      },
      templates,
      template: templates.get(0),
      templateOptions: Immutable.fromJS([{ label: 'template1', value: 'templateId' }]),
      thesauris: Immutable.fromJS([
        { _id: 2, name: 'thesauri', values: [{ label: 'option1', id: '1' }] },
      ]),
      onSubmit: jasmine.createSpy('onSubmit'),
      changeTemplate: jasmine.createSpy('changeTemplate'),
      model: 'metadata',
    };
  });

  const render = () => {
    component = shallow(<MetadataForm {...props} />);
  };

  it('should render a form with metadata as model', () => {
    render();
    const form = component.find(Form);
    expect(form.props().model).toEqual('metadata');
  });

  it('should display custom title label', () => {
    props.template = Immutable.fromJS({
      name: 'template4',
      _id: 'template4',
      commonProperties: [{ name: 'title', label: 'Name' }],
      properties: [],
    });
    render();
    const title = component.find('FormGroup').first().find({ children: 'Name' });
    expect(title.length).toBe(1);
  });

  it('should render MetadataFormFields passing thesauris state and template', () => {
    render();
    const formFields = component.find(MetadataFormFields);

    expect(formFields.props().thesauris).toBe(props.thesauris);
    expect(formFields.props().state).toBe(props.state);
    expect(formFields.props().template).toBe(props.templates.get(0));
  });

  it('should render templates sorted', () => {
    props.templateOptions = Immutable.fromJS([
      {
        label: 'Zues',
        value: 'zues',
      },
      { label: 'Yezzy', value: 'yezzy' },
      { label: 'Template1', value: 'template1' },
      { label: 'Aaron', value: 'Aaron' },
    ]);
    render();
    const templateDropdown = component.find(SimpleSelect);
    expect(templateDropdown.props().options[0].label).toEqual('Aaron');
    expect(templateDropdown.props().options[1].label).toEqual('Template1');
    expect(templateDropdown.props().options[2].label).toEqual('Yezzy');
    expect(templateDropdown.props().options[3].label).toEqual('Zues');
  });

  it('should pass the model to Form and MetadataFormFields', () => {
    render();
    const form = component.find(Form);
    expect(form.props().model).toBe('metadata');
    const metadataFields = component.find(MetadataFormFields);
    expect(metadataFields.props().model).toBe('metadata');
  });

  it('should render title field as a textarea', () => {
    render();
    expect(component.find(Field)).toMatchSnapshot();
  });

  describe('on template change', () => {
    const warningMessage = 'Changing the type will erase all relationships to this entity.';

    it('should call changeTemplate with the template', () => {
      render();
      const template = component.find(SimpleSelect).first();
      template.simulate('change', { target: { value: '2' } });
      expect(props.changeTemplate).toHaveBeenCalledWith(props.model, props.templates.toJS()[1]._id);
    });

    it('should warn about the loss of connections if the entity is already a saved one', () => {
      props.templateId = '2';
      props.initialTemplateId = 'templateId';
      render();
      const warning = component.find({ children: warningMessage });
      expect(warning.length).toBe(1);
    });

    it('should not warn about the loss of connections if the entity is a new one', () => {
      props.templateId = '2';
      props.initialTemplateId = undefined;
      render();
      const warning = component.find({ children: warningMessage });
      expect(warning.length).toBe(0);
    });

    it('should not warn about the loss of connections if the template is the same than the original one', () => {
      props.templateId = 'templateId';
      props.initialTemplateId = 'templateId';
      render();
      const warning = component.find({ children: warningMessage });
      expect(warning.length).toBe(0);
    });
  });

  describe('submit', () => {
    it('should call onSubmit with the values wrapped', () => {
      render();
      const UnwrapedEntity = {
        _id: '123',
        template: '456',
        language: 'en',
        metadata: {
          prop_one: ['one', 'two', 'three'],
          prop_two: 'Doctor who?',
          prop_three: null,
        },
        file: {},
        fullText: [],
      };
      const WrapedEntity = {
        _id: '123',
        template: '456',
        language: 'en',
        metadata: {
          prop_one: [{ value: 'one' }, { value: 'two' }, { value: 'three' }],
          prop_two: [{ value: 'Doctor who?' }],
          prop_three: [{ value: null }],
        },
      };
      component.find(Form).simulate('submit', UnwrapedEntity);
      expect(props.onSubmit).toHaveBeenCalledWith(WrapedEntity, 'metadata');
    });

    it('should disable the form while uploading supporting files', () => {
      props.progress = 50;
      render();
      expect(component.find('fieldset').props()).toMatchObject({ disabled: true });
    });

    it('should enable the form when files are not uploading', () => {
      props.progress = undefined;
      render();
      expect(component.find('fieldset').props()).toMatchObject({ disabled: false });
    });
  });

  describe('mapStateToProps', () => {
    let state;
    let ownProps;

    beforeEach(() => {
      state = {
        templates,
        metadata: { attachments: [], sharedId: 'entitySharedId' },
        attachments: { progress: Immutable.fromJS({}) },
      };
      ownProps = { templates, templateId: templates.get(1).get('_id'), model: 'metadata' };
    });

    it('should return template based on metadata.template', () => {
      expect(mapStateToProps(state, ownProps).template).toBe(templates.get(1));
    });
  });

  describe('multiple edition', () => {
    it('should not render the supporting files on edit', () => {
      props.multipleEdition = true;
      render();
      expect(component.find(SupportingFiles)).toHaveLength(0);
    });
  });
});