containers.ts 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. /**
  2. * Copyright © 2016-2020 Threema GmbH (https://threema.ch/).
  3. *
  4. * This file is part of Threema Web.
  5. *
  6. * Threema Web is free software: you can redistribute it and/or modify it
  7. * under the terms of the GNU Affero General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or (at
  9. * your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful, but
  12. * WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
  14. * General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Affero General Public License
  17. * along with Threema Web. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. // tslint:disable:no-reference
  20. /// <reference path="../../src/threema.d.ts" />
  21. import {ReceiverService} from '../../src/services/receiver';
  22. import {Conversations, StringHashSet} from '../../src/threema/container';
  23. function getConversations(): Conversations {
  24. const receiverService = new ReceiverService();
  25. return new Conversations(receiverService);
  26. }
  27. function makeContactConversation(id: string, position?: number): threema.ConversationWithPosition {
  28. return {
  29. type: 'contact',
  30. id: id,
  31. position: position,
  32. messageCount: 5,
  33. unreadCount: 0,
  34. isStarred: false,
  35. };
  36. }
  37. function getId(c: threema.Conversation): string {
  38. return c.id;
  39. }
  40. describe('Container', () => {
  41. describe('Conversations', () => {
  42. it('find', function() {
  43. const conversations = getConversations();
  44. conversations.set([
  45. makeContactConversation('1'),
  46. makeContactConversation('2'),
  47. makeContactConversation('3'),
  48. makeContactConversation('4'),
  49. ]);
  50. const receiver1: threema.BaseReceiver = { id: '2', type: 'contact' };
  51. const receiver2: threema.BaseReceiver = { id: '5', type: 'contact' };
  52. const receiver3: threema.BaseReceiver = { id: '2', type: 'me' };
  53. expect(conversations.find(receiver1)).toEqual(makeContactConversation('2'));
  54. expect(conversations.find(receiver2)).toEqual(null);
  55. expect(conversations.find(receiver3)).toEqual(null);
  56. });
  57. describe('set', function() {
  58. it('overwrites previous data', function() {
  59. const conversations = getConversations();
  60. expect(conversations.get()).toEqual([]);
  61. conversations.add(makeContactConversation('0'));
  62. expect(conversations.get().map(getId)).toEqual(['0']);
  63. conversations.set([makeContactConversation('1')]);
  64. expect(conversations.get().map(getId)).toEqual(['1']);
  65. });
  66. it('clears position field', function() {
  67. const conversations = getConversations();
  68. conversations.set([makeContactConversation('1', 7)]);
  69. const expected = makeContactConversation('1');
  70. delete expected.position;
  71. expect((conversations as any).conversations).toEqual([expected]);
  72. });
  73. it('sets defaults', function() {
  74. const conversations = getConversations();
  75. const conversation = makeContactConversation('1', 7);
  76. delete conversation.isStarred;
  77. conversations.set([conversation]);
  78. const expected = makeContactConversation('1');
  79. expect((conversations as any).conversations[0].isStarred).toEqual(false);
  80. });
  81. });
  82. describe('add', function() {
  83. it('adds a new conversation at the correct location', function() {
  84. const conversations = getConversations();
  85. expect(conversations.get()).toEqual([]);
  86. conversations.add(makeContactConversation('0', 0));
  87. conversations.add(makeContactConversation('1', 1));
  88. expect(conversations.get().map(getId)).toEqual(['0', '1']);
  89. conversations.add(makeContactConversation('2', 1));
  90. expect(conversations.get().map(getId)).toEqual(['0', '2', '1']);
  91. });
  92. });
  93. describe('updateOrAdd', function() {
  94. it('adds a new conversation at the correct location', function() {
  95. const conversations = getConversations();
  96. conversations.set([
  97. makeContactConversation('0'),
  98. makeContactConversation('1'),
  99. ]);
  100. expect(conversations.get().map(getId)).toEqual(['0', '1']);
  101. conversations.updateOrAdd(makeContactConversation('2', 2));
  102. expect(conversations.get().map(getId)).toEqual(['0', '1', '2']);
  103. conversations.updateOrAdd(makeContactConversation('3', 2));
  104. expect(conversations.get().map(getId)).toEqual(['0', '1', '3', '2']);
  105. });
  106. it('moves an existing conversation to the correct location', function() {
  107. const conversations = getConversations();
  108. conversations.set([
  109. makeContactConversation('0'),
  110. makeContactConversation('1'),
  111. makeContactConversation('2'),
  112. ]);
  113. expect(conversations.get().map(getId)).toEqual(['0', '1', '2']);
  114. conversations.updateOrAdd(makeContactConversation('2', 1));
  115. expect(conversations.get().map(getId)).toEqual(['0', '2', '1']);
  116. conversations.updateOrAdd(makeContactConversation('1', 0));
  117. expect(conversations.get().map(getId)).toEqual(['1', '0', '2']);
  118. conversations.updateOrAdd(makeContactConversation('0', 2));
  119. expect(conversations.get().map(getId)).toEqual(['1', '2', '0']);
  120. conversations.updateOrAdd(makeContactConversation('1', 7));
  121. expect(conversations.get().map(getId)).toEqual(['2', '0', '1']);
  122. });
  123. it('handles conversations that clear the latest message', function() {
  124. // Regression test for #693
  125. const conversations = getConversations();
  126. conversations.set([
  127. {
  128. type: 'contact',
  129. id: '0',
  130. position: 0,
  131. messageCount: 1,
  132. unreadCount: 0,
  133. latestMessage: {
  134. type: 'text',
  135. id: 'xyz',
  136. body: 'a',
  137. sortKey: 0,
  138. partnerId: 'z',
  139. isOutbox: true,
  140. isStatus: false,
  141. },
  142. isStarred: false,
  143. },
  144. ]);
  145. conversations.updateOrAdd({
  146. type: 'contact',
  147. id: '0',
  148. position: 0,
  149. messageCount: 0,
  150. unreadCount: 0,
  151. isStarred: false,
  152. });
  153. const updated = conversations.get()[0];
  154. expect(updated.messageCount).toEqual(0);
  155. expect(updated.latestMessage).toBeUndefined();
  156. });
  157. });
  158. });
  159. describe('StringHashSet', () => {
  160. it('clearAll', function() {
  161. const shs = new StringHashSet();
  162. shs.add('hello');
  163. shs.add('hello');
  164. shs.add('bye');
  165. expect(shs.values()).toEqual(['hello', 'bye']);
  166. shs.clearAll();
  167. expect(shs.values()).toEqual([]);
  168. });
  169. });
  170. });