<commit_before>/**
 * Copyright (c) 2013-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @emails oncall+relay
 */

'use strict';

require('configureForRelayOSS');

jest
  .dontMock('RelayMutationTransaction')
  .dontMock('RelayMutationTransactionStatus');

const Relay = require('Relay');
const RelayConnectionInterface = require('RelayConnectionInterface');
const RelayMutation = require('RelayMutation');
const RelayMutationQuery = require('RelayMutationQuery');
const RelayMutationTransactionStatus = require('RelayMutationTransactionStatus');
const RelayStore = require('RelayStore');
const RelayStoreData = require('RelayStoreData');
const RelayTestUtils = require('RelayTestUtils');

const flattenRelayQuery = require('flattenRelayQuery');
const fromGraphQL = require('fromGraphQL');

const {
  COLLISION_COMMIT_FAILED,
  COMMITTING,
  COMMIT_FAILED,
  COMMIT_QUEUED,
  CREATED,
  UNCOMMITTED,
} = RelayMutationTransactionStatus;

describe('RelayMutationQueue', () => {
  let fatQuery;
  let storeData;
  let mockMutation;
  let mutationNode;
  let mutationQueue;
  let networkLayer;

  beforeEach(() => {
    jest.resetModuleRegistry();

    RelayStoreData.prototype.handleUpdatePayload = jest.fn();
    storeData = RelayStore.getStoreData();
    mutationQueue = storeData.getMutationQueue();
    networkLayer = storeData.getNetworkLayer();
    mutationNode = Relay.QL`mutation{commentCreate(input:$input)}`;
    fatQuery = Relay.QL`fragment on Comment @relay(pattern: true) {
      ... on Comment {
        likers
        doesViewerLike
      }
    }`;
    mockMutation = new RelayMutation();
    mockMutation.getFatQuery.mockReturnValue(fatQuery);
    RelayMutation.prototype.getConfigs.mockReturnValue('configs');
    RelayMutation.prototype.getMutation.mockReturnValue(mutationNode);

    jasmine.addMatchers(RelayTestUtils.matchers);
  });

  describe('createTransaction()', () => {
    it('does not update store when creating a transaction', () => {
      const transaction = mutationQueue.createTransaction(mockMutation);

      expect(transaction.getStatus()).toBe(CREATED);
      expect(storeData.handleUpdatePayload).not.toBeCalled();
    });
  });

  describe('createTransactionWithPendingTransaction()', () => {
    it('complains if not passed a pending transaction or builder', () => {
      expect(() => mutationQueue.createTransactionWithPendingTransaction())
        .toFailInvariant(
          'RelayMutationQueue: `createTransactionWithPendingTransaction()` ' +
          'expects a PendingTransaction or TransactionBuilder.'
        );
    });
  });

  describe('applyOptimistic()', () => {
    it('applies an optimistic response', () => {
      const input = {foo: 'bar'};
      mockMutation.getVariables.mockReturnValue(input);
      mockMutation.getOptimisticResponse.mockReturnValue({});
      mockMutation.getOptimisticConfigs.mockReturnValue('optimisticConfigs');
      RelayMutationQuery.buildQuery.mockReturnValue('optimisticQuery');

      const transaction = mutationQueue.createTransaction(mockMutation);
      expect(transaction.getStatus()).toBe(CREATED);

      transaction.applyOptimistic();
      expect(transaction.getStatus()).toBe(UNCOMMITTED);

      const buildQueryCalls = RelayMutationQuery.buildQuery.mock.calls;
      expect(buildQueryCalls.length).toBe(1);
      expect(buildQueryCalls[0][0].configs).toBe('optimisticConfigs');
      expect(buildQueryCalls[0][0].input).toEqual({
        ...input,
        [RelayConnectionInterface.CLIENT_MUTATION_ID]: '0',
      });
      expect(buildQueryCalls[0][0].mutation).toBe(mutationNode);
      expect(buildQueryCalls[0][0].mutationName).toBe('RelayMutation');
      expect(buildQueryCalls[0][0].tracker).toBe(storeData.getQueryTracker());
      expect(buildQueryCalls[0][0].fatQuery).toEqualQueryNode(
        flattenRelayQuery(fromGraphQL.Fragment(fatQuery), {
          preserveEmptyNodes: true,
          shouldRemoveFragments: true,
        })
      );
      expect(storeData.handleUpdatePayload.mock.calls).toEqual([[
        'optimisticQuery',
        {[RelayConnectionInterface.CLIENT_MUTATION_ID]: '0'},
        {configs: 'optimisticConfigs', isOptimisticUpdate: true},
      ]]);
    });

    it('infers optimistic query if mutation does not have one', () => {
      mockMutation.getOptimisticResponse.mockReturnValue({});
      RelayMutationQuery.buildQueryForOptimisticUpdate.mockReturnValue(
        'optimisticQuery'
      );

      mutationQueue.createTransaction(mockMutation).applyOptimistic();

      const buildQueryCalls =
        RelayMutationQuery.buildQueryForOptimisticUpdate.mock.calls;
      expect(buildQueryCalls.length).toBe(1);
      expect(buildQueryCalls[0][0].mutation).toBe(mutationNode);
      expect(buildQueryCalls[0][0].response).toEqual({
        [RelayConnectionInterface.CLIENT_MUTATION_ID]: '0',
      });
      expect(buildQueryCalls[0][0].tracker).toBe(storeData.getQueryTracker());
      expect(buildQueryCalls[0][0].fatQuery).toEqualQueryNode(
        flattenRelayQuery(fromGraphQL.Fragment(fatQuery), {
          preserveEmptyNodes: true,
          shouldRemoveFragments: true,
        })
      );
      expect(storeData.handleUpdatePayload.mock.calls).toEqual([[
        'optimisticQuery',
        {[RelayConnectionInterface.CLIENT_MUTATION_ID]: '0'},
        {configs: 'configs', isOptimisticUpdate: true},
      ]]);
    });
  });

  describe('commit()', () => {
    let mockMutation1;
    let mockMutation2;
    let mockMutation3;

    beforeEach(() => {
      RelayMutation.prototype.getFatQuery.mockReturnValue(fatQuery);
      RelayMutation.prototype.getCollisionKey.mockReturnValue(null);
      RelayMutation.prototype.getVariables.mockReturnValue({});
<commit_msg>Fix test failures in RelayMutationQueue<commit_after>/**
 * Copyright (c) 2013-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @emails oncall+relay
 */

'use strict';

require('configureForRelayOSS');

jest
  .dontMock('RelayMutationTransaction')
  .dontMock('RelayMutationTransactionStatus');

const Relay = require('Relay');
const RelayConnectionInterface = require('RelayConnectionInterface');
const RelayMutation = require('RelayMutation');
const RelayMutationQuery = require('RelayMutationQuery');
const RelayMutationTransactionStatus = require('RelayMutationTransactionStatus');
const RelayStore = require('RelayStore');
const RelayStoreData = require('RelayStoreData');
const RelayTestUtils = require('RelayTestUtils');

const flattenRelayQuery = require('flattenRelayQuery');
const fromGraphQL = require('fromGraphQL');

const {
  COLLISION_COMMIT_FAILED,
  COMMITTING,
  COMMIT_FAILED,
  COMMIT_QUEUED,
  CREATED,
  UNCOMMITTED,
} = RelayMutationTransactionStatus;

describe('RelayMutationQueue', () => {
  let fatQuery;
  let storeData;
  let mockMutation;
  let mutationNode;
  let mutationQueue;
  let networkLayer;

  beforeEach(() => {
    jest.resetModuleRegistry();

    RelayStoreData.prototype.handleUpdatePayload = jest.fn();
    storeData = RelayStore.getStoreData();
    mutationQueue = storeData.getMutationQueue();
    networkLayer = storeData.getNetworkLayer();
    mutationNode = Relay.QL`mutation{commentCreate(input:$input)}`;
    fatQuery = Relay.QL`fragment on Comment @relay(pattern: true) {
      ... on Comment {
        likers
        doesViewerLike
      }
    }`;
    mockMutation = new RelayMutation();
    mockMutation.getFatQuery.mockReturnValue(fatQuery);
    RelayMutation.prototype.getConfigs.mockReturnValue('configs');
    RelayMutation.prototype.getMutation.mockReturnValue(mutationNode);

    jasmine.addMatchers(RelayTestUtils.matchers);
  });

  describe('createTransaction()', () => {
    it('does not update store when creating a transaction', () => {
      const transaction = mutationQueue.createTransaction(mockMutation);

      expect(transaction.getStatus()).toBe(CREATED);
      expect(storeData.handleUpdatePayload).not.toBeCalled();
    });
  });

  describe('createTransactionWithPendingTransaction()', () => {
    it('complains if not passed a pending transaction or builder', () => {
      expect(() => mutationQueue.createTransactionWithPendingTransaction())
        .toFailInvariant(
          'RelayMutationQueue: `createTransactionWithPendingTransaction()` ' +
          'expects a PendingTransaction or TransactionBuilder.'
        );
    });
  });

  describe('applyOptimistic()', () => {
    it('applies an optimistic response', () => {
      const input = {foo: 'bar'};
      mockMutation.getVariables.mockReturnValue(input);
      mockMutation.getOptimisticResponse.mockReturnValue({});
      mockMutation.getOptimisticConfigs.mockReturnValue('optimisticConfigs');
      RelayMutationQuery.buildQuery.mockReturnValue('optimisticQuery');

      const transaction = mutationQueue.createTransaction(mockMutation);
      expect(transaction.getStatus()).toBe(CREATED);

      transaction.applyOptimistic();
      expect(transaction.getStatus()).toBe(UNCOMMITTED);

      const buildQueryCalls = RelayMutationQuery.buildQuery.mock.calls;
      expect(buildQueryCalls.length).toBe(1);
      expect(buildQueryCalls[0][0].configs).toBe('optimisticConfigs');
      expect(buildQueryCalls[0][0].input).toEqual({
        ...input,
        [RelayConnectionInterface.CLIENT_MUTATION_ID]: '0',
      });
      expect(buildQueryCalls[0][0].mutation).toBe(mutationNode);
      expect(buildQueryCalls[0][0].mutationName).toBe('RelayMutation');
      expect(buildQueryCalls[0][0].tracker).toBe(storeData.getQueryTracker());
      expect(buildQueryCalls[0][0].fatQuery).toEqualQueryNode(
        flattenRelayQuery(fromGraphQL.Fragment(fatQuery), {
          preserveEmptyNodes: true,
          shouldRemoveFragments: true,
        })
      );
      expect(storeData.handleUpdatePayload.mock.calls).toEqual([[
        'optimisticQuery',
        {[RelayConnectionInterface.CLIENT_MUTATION_ID]: '0'},
        {configs: 'optimisticConfigs', isOptimisticUpdate: true},
      ]]);
    });

    it('infers optimistic query if mutation does not have one', () => {
      mockMutation.getOptimisticResponse.mockReturnValue({});
      RelayMutationQuery.buildQueryForOptimisticUpdate.mockReturnValue(
        'optimisticQuery'
      );

      mutationQueue.createTransaction(mockMutation).applyOptimistic();

      const buildQueryCalls =
        RelayMutationQuery.buildQueryForOptimisticUpdate.mock.calls;
      expect(buildQueryCalls.length).toBe(1);
      expect(buildQueryCalls[0][0].mutation).toBe(mutationNode);
      expect(buildQueryCalls[0][0].response).toEqual({
        [RelayConnectionInterface.CLIENT_MUTATION_ID]: '0',
      });
      expect(buildQueryCalls[0][0].fatQuery).toEqualQueryNode(
        flattenRelayQuery(fromGraphQL.Fragment(fatQuery), {
          preserveEmptyNodes: true,
          shouldRemoveFragments: true,
        })
      );
      expect(storeData.handleUpdatePayload.mock.calls).toEqual([[
        'optimisticQuery',
        {[RelayConnectionInterface.CLIENT_MUTATION_ID]: '0'},
        {configs: 'configs', isOptimisticUpdate: true},
      ]]);
    });
  });

  describe('commit()', () => {
    let mockMutation1;
    let mockMutation2;
    let mockMutation3;

    beforeEach(() => {
      RelayMutation.prototype.getFatQuery.mockReturnValue(fatQuery);
      RelayMutation.prototype.getCollisionKey.mockReturnValue(null);
      RelayMutation.prototype.getVariables.mockReturnValue({});

{'fraction_non_alphanumeric': 0.12283810005905678, 'fraction_numerical': 0.005399476925672825, 'mean_word_length': 4.270787016451757, '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': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1454669', 'n_tokens_mistral': 3502, 'n_tokens_neox': 3445, 'n_words': 527}