<commit_before>import R from 'ramda';
import chai from 'chai';
import thunk from 'redux-thunk';
import { createStore, applyMiddleware } from 'redux';
import generateReducers from '../../app/reducers/';
import { nodes } from '../../app/reducers/nodes';
import * as Actions from '../../app/actions';
import Selectors from '../../app/selectors';
import * as PIN_DIRECTION from '../../app/constants/pinDirection';

const mockStore = (state) => createStore(generateReducers([1]), state, applyMiddleware(thunk));

describe('Project reducer: ', () => {
  const projectShape = {
    project: {
      meta: {},
      patches: {
        1: {
          present: {
            nodes: {},
            pins: {},
            links: {},
          },
        },
      },
      nodeTypes: {},
      counter: {
        patches: 1,
        nodes: 0,
        pins: 0,
        links: 0,
      },
    },
  };

  describe('Add node', () => {
    const mockState = R.assocPath(
      ['project', 'nodeTypes', 1],
      {
        id: 1,
        pins: {
          in: {
            key: 'in',
            direction: PIN_DIRECTION.INPUT,
          },
          out: {
            key: 'out',
            direction: PIN_DIRECTION.OUTPUT,
          },
        },
      },
      projectShape
    );

    let store;
    beforeEach(() => {
      store = mockStore(mockState);
    });

    it('should add node and children pins', () => {
      const patchId = 1;
      const expectedNodes = {
        1: {
          id: 1,
          typeId: 1,
          position: {
            x: 10,
            y: 10,
          },
          properties: {},
        },
      };
      const expectedPins = {
        1: {
          id: 1,
          nodeId: 1,
          key: 'in',
        },
        2: {
          id: 2,
          nodeId: 1,
          key: 'out',
        },
      };
      store.dispatch(Actions.addNode(1, { x: 10, y: 10 }, patchId));

      const projectState = Selectors.Project.getProject(store.getState());
      const patchState = Selectors.Project.getPatchById(projectState, patchId);

      chai.expect(patchState.nodes).to.deep.equal(expectedNodes);
      chai.expect(patchState.pins).to.deep.equal(expectedPins);
    });

    it('should be undoable and redoable', () => {
      const patchId = 1;
      const initialProjectState = Selectors.Project.getProject(store.getState());
      const initialPatchState = Selectors.Project.getPatchById(initialProjectState, patchId);

      store.dispatch(Actions.addNode(1, { x: 10, y: 10 }, patchId));
      const updatedProjectState = Selectors.Project.getProject(store.getState());
      const updatedPatchState = Selectors.Project.getPatchById(updatedProjectState, patchId);

      store.dispatch(Actions.undoPatch(patchId));
      const undoedProjectState = Selectors.Project.getProject(store.getState());
      const undoedPatchState = Selectors.Project.getPatchById(undoedProjectState, patchId);

      store.dispatch(Actions.redoPatch(patchId));
      const redoedProjectState = Selectors.Project.getProject(store.getState());
      const redoedPatchState = Selectors.Project.getPatchById(redoedProjectState, patchId);

      chai.expect(undoedPatchState).to.deep.equal(initialPatchState);
      chai.expect(redoedPatchState).to.deep.equal(updatedPatchState);
    });
  });

  describe('Delete node', () => {
    const mockState = {
      project: {
        nodes: {
          1: {
            id: 1,
          },
          2: {
            id: 2,
          },
        },
        pins: {
          1: {
            id: 1,
            nodeId: 1,
          },
          2: {
            id: 2,
            nodeId: 1,
          },
          3: {
            id: 3,
            nodeId: 2,
          },
        },
        links: {
          1: {
            id: 1,
            pins: [2, 3],
          },
        },
        nodeTypes: {},
        meta: {},
        patches: {},
      },
    };

    let store;
    beforeEach(() => {
      store = mockStore(mockState);
    });

    it('should delete node, children pins and link', () => {
      const expectedNodes = {
        2: { id: 2 },
      };
      const expectedPins = {
        3: { id: 3, nodeId: 2 },
      };
      const expectedLinks = {};

      store.dispatch(Actions.deleteNode(1));

      const projectStore = Selectors.Project.getProject(store.getState());

      chai.expect(projectStore.nodes).to.deep.equal(expectedNodes);
      chai.expect(projectStore.pins).to.deep.equal(expectedPins);
      chai.expect(projectStore.links).to.deep.equal(expectedLinks);
    });

    it('should be undoable and redoable', () => {
      store.dispatch(Actions.deleteNode(1));
      const updatedStore = Selectors.Project.getProject(store.getState());
      store.dispatch(ReduxUndoActions.undo());
      const undoedStore = Selectors.Project.getProject(store.getState());
      store.dispatch(ReduxUndoActions.redo());
      const redoedStore = Selectors.Project.getProject(store.getState());
      chai.expect(undoedStore).to.deep.equal(mockState.project);
      chai.expect(redoedStore).to.deep.equal(updatedStore);
    });
  });

  describe('Moving node', () => {
    let nodeStore = null;

    beforeEach(() => {
      nodeStore = {
        1: {
          id: 1,
          position: {
            x: 0,<commit_msg>fix(test): fix delete node tests<commit_after>import R from 'ramda';
import chai from 'chai';
import thunk from 'redux-thunk';
import { createStore, applyMiddleware } from 'redux';
import generateReducers from '../../app/reducers/';
import { nodes } from '../../app/reducers/nodes';
import * as Actions from '../../app/actions';
import Selectors from '../../app/selectors';
import * as PIN_DIRECTION from '../../app/constants/pinDirection';

const mockStore = (state) => createStore(generateReducers([1]), state, applyMiddleware(thunk));

describe('Project reducer: ', () => {
  const projectShape = {
    project: {
      meta: {},
      patches: {
        1: {
          present: {
            id: 1,
            nodes: {},
            pins: {},
            links: {},
          },
        },
      },
      nodeTypes: {},
      counter: {
        patches: 1,
        nodes: 0,
        pins: 0,
        links: 0,
      },
    },
  };

  describe('Add node', () => {
    const mockState = R.assocPath(
      ['project', 'nodeTypes', 1],
      {
        id: 1,
        pins: {
          in: {
            key: 'in',
            direction: PIN_DIRECTION.INPUT,
          },
          out: {
            key: 'out',
            direction: PIN_DIRECTION.OUTPUT,
          },
        },
      },
      projectShape
    );

    let store;
    beforeEach(() => {
      store = mockStore(mockState);
    });

    it('should add node and children pins', () => {
      const patchId = 1;
      const expectedNodes = {
        1: {
          id: 1,
          typeId: 1,
          position: {
            x: 10,
            y: 10,
          },
          properties: {},
        },
      };
      const expectedPins = {
        1: {
          id: 1,
          nodeId: 1,
          key: 'in',
        },
        2: {
          id: 2,
          nodeId: 1,
          key: 'out',
        },
      };
      store.dispatch(Actions.addNode(1, { x: 10, y: 10 }, patchId));

      const projectState = Selectors.Project.getProject(store.getState());
      const patchState = Selectors.Project.getPatchById(projectState, patchId);

      chai.expect(patchState.nodes).to.deep.equal(expectedNodes);
      chai.expect(patchState.pins).to.deep.equal(expectedPins);
    });

    it('should be undoable and redoable', () => {
      const patchId = 1;
      const initialProjectState = Selectors.Project.getProject(store.getState());
      const initialPatchState = Selectors.Project.getPatchById(initialProjectState, patchId);

      store.dispatch(Actions.addNode(1, { x: 10, y: 10 }, patchId));
      const updatedProjectState = Selectors.Project.getProject(store.getState());
      const updatedPatchState = Selectors.Project.getPatchById(updatedProjectState, patchId);

      store.dispatch(Actions.undoPatch(patchId));
      const undoedProjectState = Selectors.Project.getProject(store.getState());
      const undoedPatchState = Selectors.Project.getPatchById(undoedProjectState, patchId);

      store.dispatch(Actions.redoPatch(patchId));
      const redoedProjectState = Selectors.Project.getProject(store.getState());
      const redoedPatchState = Selectors.Project.getPatchById(redoedProjectState, patchId);

      chai.expect(undoedPatchState).to.deep.equal(initialPatchState);
      chai.expect(redoedPatchState).to.deep.equal(updatedPatchState);
    });
  });

  describe('Delete node', () => {
    const patchPath = ['project', 'patches', 1];
    const mockState = R.pipe(
      R.dissocPath(['project', 'patches', 1, 'present']),
      R.assocPath(
        patchPath,
        {
          id: 1,
        }
      ),
      R.assocPath(
        R.append('nodes', patchPath),
        {
          1: {
            id: 1,
          },
          2: {
            id: 2,
          },
        }
      ),
      R.assocPath(
        R.append('pins', patchPath),
        {
          1: {
            id: 1,
            nodeId: 1,
          },
          2: {
            id: 2,
            nodeId: 1,
          },
          3: {
            id: 3,
            nodeId: 2,
          },
        }
      ),
      R.assocPath(
        R.append('links', patchPath),
        {
          1: {
            id: 1,
            pins: [2, 3],
          },
        }
      ),
      R.assocPath(
        ['project', 'counter'],
        {
          nodes: 2,
          pins: 3,
          links: 1,
        }
      )
    )(projectShape);

    let store;
    beforeEach(() => {
      store = mockStore(mockState);
    });

    it('should delete node, children pins and link', () => {
      const patchId = 1;
      const expectedNodes = { 2: { id: 2 } };
      const expectedPins = { 3: { id: 3, nodeId: 2 } };
      const expectedLinks = {};

      store.dispatch(Actions.deleteNode(1));

      const projectState = Selectors.Project.getProject(store.getState());
      const patchState = Selectors.Project.getPatchById(projectState, patchId);

      chai.expect(patchState.nodes).to.deep.equal(expectedNodes);
      chai.expect(patchState.pins).to.deep.equal(expectedPins);
      chai.expect(patchState.links).to.deep.equal(expectedLinks);
    });

    it('should be undoable and redoable', () => {
      const patchId = 1;
      const initialProjectState = Selectors.Project.getProject(store.getState());
      const initialPatchState = Selectors.Project.getPatchById(initialProjectState, patchId);

      store.dispatch(Actions.deleteNode(1));
      const updatedProjectState = Selectors.Project.getProject(store.getState());
      const updatedPatchState = Selectors.Project.getPatchById(updatedProjectState, patchId);

      store.dispatch(Actions.undoPatch(patchId));
      const undoedProjectState = Selectors.Project.getProject(store.getState());
      const undoedPatchState = Selectors.Project.getPatchById(undoedProjectState, patchId);

      store.dispatch(Actions.redoPatch(patchId));
      const redoedProjectState = Selectors.Project.getProject(store.getState());
      const redoedPatchState = Selectors.Project.getPatchById(redoedProjectState, patchId);

      chai.expect(undoedPatchState).to.deep.equal(initialPatchState);
      chai.expect(redoedPatchState).to.deep.equal(updatedPatchState);
    });
  });

  describe('Moving node', () => {
    let nodeStore = null;

    beforeEach(() => {
      nodeStore = {
        1: {
          id: 1,
          position: {
            x: 0,
{'fraction_non_alphanumeric': 0.14030721702565863, 'fraction_numerical': 0.01107011070110701, 'mean_word_length': 1.9782775364170713, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3839860', 'n_tokens_mistral': 3609, 'n_tokens_neox': 3446, 'n_words': 652}