342 lines
		
	
	
	
		
			9.9 KiB
			
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			342 lines
		
	
	
	
		
			9.9 KiB
			
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
// Copyright 2021 Signal Messenger, LLC
 | 
						|
// SPDX-License-Identifier: AGPL-3.0-only
 | 
						|
 | 
						|
import { assert } from 'chai';
 | 
						|
import * as sinon from 'sinon';
 | 
						|
import { v4 as uuid } from 'uuid';
 | 
						|
import { RowType } from '../../../components/ConversationList';
 | 
						|
import { FindDirection } from '../../../components/leftPane/LeftPaneHelper';
 | 
						|
import { getDefaultConversation } from '../../../test-both/helpers/getDefaultConversation';
 | 
						|
import { LeftPaneSearchHelper } from '../../../components/leftPane/LeftPaneSearchHelper';
 | 
						|
 | 
						|
import { LeftPaneArchiveHelper } from '../../../components/leftPane/LeftPaneArchiveHelper';
 | 
						|
 | 
						|
describe('LeftPaneArchiveHelper', () => {
 | 
						|
  let sandbox: sinon.SinonSandbox;
 | 
						|
 | 
						|
  const defaults = {
 | 
						|
    archivedConversations: [],
 | 
						|
    searchConversation: undefined,
 | 
						|
    searchTerm: '',
 | 
						|
    startSearchCounter: 0,
 | 
						|
  };
 | 
						|
 | 
						|
  const searchingDefaults = {
 | 
						|
    ...defaults,
 | 
						|
    searchConversation: getDefaultConversation(),
 | 
						|
    conversationResults: { isLoading: false, results: [] },
 | 
						|
    contactResults: { isLoading: false, results: [] },
 | 
						|
    messageResults: { isLoading: false, results: [] },
 | 
						|
    searchTerm: 'foo',
 | 
						|
    primarySendsSms: false,
 | 
						|
  };
 | 
						|
 | 
						|
  beforeEach(() => {
 | 
						|
    sandbox = sinon.createSandbox();
 | 
						|
  });
 | 
						|
 | 
						|
  afterEach(() => {
 | 
						|
    sandbox.restore();
 | 
						|
  });
 | 
						|
 | 
						|
  describe('getBackAction', () => {
 | 
						|
    it('returns the "show inbox" action', () => {
 | 
						|
      const showInbox = sinon.fake();
 | 
						|
      const helper = new LeftPaneArchiveHelper(defaults);
 | 
						|
 | 
						|
      assert.strictEqual(helper.getBackAction({ showInbox }), showInbox);
 | 
						|
    });
 | 
						|
  });
 | 
						|
 | 
						|
  describe('getRowCount', () => {
 | 
						|
    it('returns the number of archived conversations', () => {
 | 
						|
      assert.strictEqual(new LeftPaneArchiveHelper(defaults).getRowCount(), 0);
 | 
						|
      assert.strictEqual(
 | 
						|
        new LeftPaneArchiveHelper({
 | 
						|
          ...defaults,
 | 
						|
          archivedConversations: [
 | 
						|
            getDefaultConversation(),
 | 
						|
            getDefaultConversation(),
 | 
						|
          ],
 | 
						|
        }).getRowCount(),
 | 
						|
        2
 | 
						|
      );
 | 
						|
    });
 | 
						|
 | 
						|
    it('defers to the search helper if searching', () => {
 | 
						|
      sandbox.stub(LeftPaneSearchHelper.prototype, 'getRowCount').returns(123);
 | 
						|
      assert.strictEqual(
 | 
						|
        new LeftPaneArchiveHelper(searchingDefaults).getRowCount(),
 | 
						|
        123
 | 
						|
      );
 | 
						|
    });
 | 
						|
  });
 | 
						|
 | 
						|
  describe('getRowIndexToScrollTo', () => {
 | 
						|
    it('returns undefined if no conversation is selected', () => {
 | 
						|
      const helper = new LeftPaneArchiveHelper({
 | 
						|
        ...defaults,
 | 
						|
        archivedConversations: [
 | 
						|
          getDefaultConversation(),
 | 
						|
          getDefaultConversation(),
 | 
						|
        ],
 | 
						|
      });
 | 
						|
 | 
						|
      assert.isUndefined(helper.getRowIndexToScrollTo(undefined));
 | 
						|
    });
 | 
						|
 | 
						|
    it('returns undefined if the selected conversation is not pinned or non-pinned', () => {
 | 
						|
      const helper = new LeftPaneArchiveHelper({
 | 
						|
        ...defaults,
 | 
						|
        archivedConversations: [
 | 
						|
          getDefaultConversation(),
 | 
						|
          getDefaultConversation(),
 | 
						|
        ],
 | 
						|
      });
 | 
						|
 | 
						|
      assert.isUndefined(helper.getRowIndexToScrollTo(uuid()));
 | 
						|
    });
 | 
						|
 | 
						|
    it("returns the archived conversation's index", () => {
 | 
						|
      const archivedConversations = [
 | 
						|
        getDefaultConversation(),
 | 
						|
        getDefaultConversation(),
 | 
						|
      ];
 | 
						|
      const helper = new LeftPaneArchiveHelper({
 | 
						|
        ...defaults,
 | 
						|
        archivedConversations,
 | 
						|
      });
 | 
						|
 | 
						|
      assert.strictEqual(
 | 
						|
        helper.getRowIndexToScrollTo(archivedConversations[0].id),
 | 
						|
        0
 | 
						|
      );
 | 
						|
      assert.strictEqual(
 | 
						|
        helper.getRowIndexToScrollTo(archivedConversations[1].id),
 | 
						|
        1
 | 
						|
      );
 | 
						|
    });
 | 
						|
 | 
						|
    it('defers to the search helper if searching', () => {
 | 
						|
      sandbox
 | 
						|
        .stub(LeftPaneSearchHelper.prototype, 'getRowIndexToScrollTo')
 | 
						|
        .returns(123);
 | 
						|
 | 
						|
      const archivedConversations = [
 | 
						|
        getDefaultConversation(),
 | 
						|
        getDefaultConversation(),
 | 
						|
      ];
 | 
						|
      const helper = new LeftPaneArchiveHelper(searchingDefaults);
 | 
						|
 | 
						|
      assert.strictEqual(
 | 
						|
        helper.getRowIndexToScrollTo(archivedConversations[0].id),
 | 
						|
        123
 | 
						|
      );
 | 
						|
    });
 | 
						|
  });
 | 
						|
 | 
						|
  describe('getRow', () => {
 | 
						|
    it('returns each conversation as a row', () => {
 | 
						|
      const archivedConversations = [
 | 
						|
        getDefaultConversation(),
 | 
						|
        getDefaultConversation(),
 | 
						|
      ];
 | 
						|
      const helper = new LeftPaneArchiveHelper({
 | 
						|
        ...defaults,
 | 
						|
        archivedConversations,
 | 
						|
      });
 | 
						|
 | 
						|
      assert.deepEqual(helper.getRow(0), {
 | 
						|
        type: RowType.Conversation,
 | 
						|
        conversation: archivedConversations[0],
 | 
						|
      });
 | 
						|
      assert.deepEqual(helper.getRow(1), {
 | 
						|
        type: RowType.Conversation,
 | 
						|
        conversation: archivedConversations[1],
 | 
						|
      });
 | 
						|
    });
 | 
						|
 | 
						|
    it('defers to the search helper if searching', () => {
 | 
						|
      sandbox
 | 
						|
        .stub(LeftPaneSearchHelper.prototype, 'getRow')
 | 
						|
        .returns({ type: RowType.SearchResultsLoadingFakeHeader });
 | 
						|
 | 
						|
      const helper = new LeftPaneArchiveHelper(searchingDefaults);
 | 
						|
 | 
						|
      assert.deepEqual(helper.getRow(0), {
 | 
						|
        type: RowType.SearchResultsLoadingFakeHeader,
 | 
						|
      });
 | 
						|
    });
 | 
						|
  });
 | 
						|
 | 
						|
  describe('getConversationAndMessageAtIndex', () => {
 | 
						|
    it('returns the conversation at the given index when it exists', () => {
 | 
						|
      const archivedConversations = [
 | 
						|
        getDefaultConversation(),
 | 
						|
        getDefaultConversation(),
 | 
						|
      ];
 | 
						|
      const helper = new LeftPaneArchiveHelper({
 | 
						|
        ...defaults,
 | 
						|
        archivedConversations,
 | 
						|
      });
 | 
						|
 | 
						|
      assert.strictEqual(
 | 
						|
        helper.getConversationAndMessageAtIndex(0)?.conversationId,
 | 
						|
        archivedConversations[0].id
 | 
						|
      );
 | 
						|
      assert.strictEqual(
 | 
						|
        helper.getConversationAndMessageAtIndex(1)?.conversationId,
 | 
						|
        archivedConversations[1].id
 | 
						|
      );
 | 
						|
    });
 | 
						|
 | 
						|
    it('when requesting an index out of bounds, returns the last conversation', () => {
 | 
						|
      const archivedConversations = [
 | 
						|
        getDefaultConversation(),
 | 
						|
        getDefaultConversation(),
 | 
						|
      ];
 | 
						|
      const helper = new LeftPaneArchiveHelper({
 | 
						|
        ...defaults,
 | 
						|
        archivedConversations,
 | 
						|
      });
 | 
						|
 | 
						|
      assert.strictEqual(
 | 
						|
        helper.getConversationAndMessageAtIndex(2)?.conversationId,
 | 
						|
        archivedConversations[1].id
 | 
						|
      );
 | 
						|
      assert.strictEqual(
 | 
						|
        helper.getConversationAndMessageAtIndex(99)?.conversationId,
 | 
						|
        archivedConversations[1].id
 | 
						|
      );
 | 
						|
 | 
						|
      // This is mostly a resilience measure in case we're ever called with an invalid
 | 
						|
      //   index.
 | 
						|
      assert.strictEqual(
 | 
						|
        helper.getConversationAndMessageAtIndex(-1)?.conversationId,
 | 
						|
        archivedConversations[1].id
 | 
						|
      );
 | 
						|
    });
 | 
						|
 | 
						|
    it('returns undefined if there are no archived conversations', () => {
 | 
						|
      const helper = new LeftPaneArchiveHelper(defaults);
 | 
						|
 | 
						|
      assert.isUndefined(helper.getConversationAndMessageAtIndex(0));
 | 
						|
      assert.isUndefined(helper.getConversationAndMessageAtIndex(1));
 | 
						|
      assert.isUndefined(helper.getConversationAndMessageAtIndex(-1));
 | 
						|
    });
 | 
						|
 | 
						|
    it('defers to the search helper if searching', () => {
 | 
						|
      sandbox
 | 
						|
        .stub(
 | 
						|
          LeftPaneSearchHelper.prototype,
 | 
						|
          'getConversationAndMessageAtIndex'
 | 
						|
        )
 | 
						|
        .returns({ conversationId: 'abc123' });
 | 
						|
 | 
						|
      const helper = new LeftPaneArchiveHelper(searchingDefaults);
 | 
						|
 | 
						|
      assert.deepEqual(helper.getConversationAndMessageAtIndex(999), {
 | 
						|
        conversationId: 'abc123',
 | 
						|
      });
 | 
						|
    });
 | 
						|
  });
 | 
						|
 | 
						|
  describe('getConversationAndMessageInDirection', () => {
 | 
						|
    it('returns the next conversation when searching downward', () => {
 | 
						|
      const archivedConversations = [
 | 
						|
        getDefaultConversation(),
 | 
						|
        getDefaultConversation(),
 | 
						|
      ];
 | 
						|
      const helper = new LeftPaneArchiveHelper({
 | 
						|
        ...defaults,
 | 
						|
        archivedConversations,
 | 
						|
      });
 | 
						|
 | 
						|
      assert.deepEqual(
 | 
						|
        helper.getConversationAndMessageInDirection(
 | 
						|
          { direction: FindDirection.Down, unreadOnly: false },
 | 
						|
          archivedConversations[0].id,
 | 
						|
          undefined
 | 
						|
        ),
 | 
						|
        { conversationId: archivedConversations[1].id }
 | 
						|
      );
 | 
						|
    });
 | 
						|
 | 
						|
    // Additional tests are found with `getConversationInDirection`.
 | 
						|
 | 
						|
    it('defers to the search helper if searching', () => {
 | 
						|
      sandbox
 | 
						|
        .stub(
 | 
						|
          LeftPaneSearchHelper.prototype,
 | 
						|
          'getConversationAndMessageInDirection'
 | 
						|
        )
 | 
						|
        .returns({ conversationId: 'abc123' });
 | 
						|
 | 
						|
      const helper = new LeftPaneArchiveHelper(searchingDefaults);
 | 
						|
 | 
						|
      assert.deepEqual(
 | 
						|
        helper.getConversationAndMessageInDirection(
 | 
						|
          {
 | 
						|
            direction: FindDirection.Down,
 | 
						|
            unreadOnly: false,
 | 
						|
          },
 | 
						|
          getDefaultConversation().id,
 | 
						|
          undefined
 | 
						|
        ),
 | 
						|
        {
 | 
						|
          conversationId: 'abc123',
 | 
						|
        }
 | 
						|
      );
 | 
						|
    });
 | 
						|
  });
 | 
						|
 | 
						|
  describe('shouldRecomputeRowHeights', () => {
 | 
						|
    it('returns false when not searching because row heights are constant', () => {
 | 
						|
      const helper = new LeftPaneArchiveHelper({
 | 
						|
        ...defaults,
 | 
						|
        archivedConversations: [
 | 
						|
          getDefaultConversation(),
 | 
						|
          getDefaultConversation(),
 | 
						|
        ],
 | 
						|
      });
 | 
						|
 | 
						|
      assert.isFalse(
 | 
						|
        helper.shouldRecomputeRowHeights({
 | 
						|
          ...defaults,
 | 
						|
          archivedConversations: [getDefaultConversation()],
 | 
						|
        })
 | 
						|
      );
 | 
						|
      assert.isFalse(
 | 
						|
        helper.shouldRecomputeRowHeights({
 | 
						|
          ...defaults,
 | 
						|
          archivedConversations: [
 | 
						|
            getDefaultConversation(),
 | 
						|
            getDefaultConversation(),
 | 
						|
          ],
 | 
						|
        })
 | 
						|
      );
 | 
						|
    });
 | 
						|
 | 
						|
    it('returns true when going from searching → not searching', () => {
 | 
						|
      const helper = new LeftPaneArchiveHelper(defaults);
 | 
						|
 | 
						|
      assert.isTrue(helper.shouldRecomputeRowHeights(searchingDefaults));
 | 
						|
    });
 | 
						|
 | 
						|
    it('returns true when going from not searching → searching', () => {
 | 
						|
      const helper = new LeftPaneArchiveHelper(searchingDefaults);
 | 
						|
 | 
						|
      assert.isTrue(helper.shouldRecomputeRowHeights(defaults));
 | 
						|
    });
 | 
						|
 | 
						|
    it('defers to the search helper if searching', () => {
 | 
						|
      sandbox
 | 
						|
        .stub(LeftPaneSearchHelper.prototype, 'shouldRecomputeRowHeights')
 | 
						|
        .returns(true);
 | 
						|
 | 
						|
      const helper = new LeftPaneArchiveHelper(searchingDefaults);
 | 
						|
 | 
						|
      assert.isTrue(helper.shouldRecomputeRowHeights(searchingDefaults));
 | 
						|
    });
 | 
						|
  });
 | 
						|
});
 |