/Signal/src/ViewControllers/DebugUI/DebugUIStress.m

https://gitlab.com/kush/signalios · Objective C · 567 lines · 525 code · 37 blank · 5 comment · 8 complexity · c801487f225fb5d701b9eacc79584c98 MD5 · raw file

  1. //
  2. // Copyright (c) 2019 Open Whisper Systems. All rights reserved.
  3. //
  4. #import "DebugUIStress.h"
  5. #import "OWSMessageSender.h"
  6. #import "OWSTableViewController.h"
  7. #import "SignalApp.h"
  8. #import "ThreadUtil.h"
  9. #import <SignalCoreKit/Cryptography.h>
  10. #import <SignalCoreKit/NSDate+OWS.h>
  11. #import <SignalCoreKit/Randomness.h>
  12. #import <SignalMessaging/Environment.h>
  13. #import <SignalServiceKit/OWSDynamicOutgoingMessage.h>
  14. #import <SignalServiceKit/SignalServiceKit-Swift.h>
  15. #import <SignalServiceKit/TSAccountManager.h>
  16. #import <SignalServiceKit/TSGroupThread.h>
  17. #import <SignalServiceKit/TSThread.h>
  18. #ifdef DEBUG
  19. NS_ASSUME_NONNULL_BEGIN
  20. @implementation DebugUIStress
  21. #pragma mark - Dependencies
  22. + (MessageSenderJobQueue *)messageSenderJobQueue
  23. {
  24. return SSKEnvironment.shared.messageSenderJobQueue;
  25. }
  26. - (MessageSenderJobQueue *)messageSenderJobQueue
  27. {
  28. return self.class.messageSenderJobQueue;
  29. }
  30. + (SDSDatabaseStorage *)databaseStorage
  31. {
  32. return SDSDatabaseStorage.shared;
  33. }
  34. + (TSAccountManager *)tsAccountManager
  35. {
  36. return TSAccountManager.sharedInstance;
  37. }
  38. #pragma mark - Factory Methods
  39. - (NSString *)name
  40. {
  41. return @"Stress";
  42. }
  43. - (nullable OWSTableSection *)sectionForThread:(nullable TSThread *)thread
  44. {
  45. OWSAssertDebug(thread);
  46. NSMutableArray<OWSTableItem *> *items = [NSMutableArray new];
  47. [items addObject:[OWSTableItem itemWithTitle:@"Send empty message"
  48. actionBlock:^{
  49. [DebugUIStress sendStressMessage:thread block:^(SignalRecipient *recipient) {
  50. return [NSData new];
  51. }];
  52. }]];
  53. [items addObject:[OWSTableItem itemWithTitle:@"Send random noise message"
  54. actionBlock:^{
  55. [DebugUIStress
  56. sendStressMessage:thread
  57. block:^(SignalRecipient *recipient) {
  58. NSUInteger contentLength = arc4random_uniform(32);
  59. return [Cryptography generateRandomBytes:contentLength];
  60. }];
  61. }]];
  62. [items addObject:[OWSTableItem itemWithTitle:@"Send no payload message"
  63. actionBlock:^{
  64. [DebugUIStress sendStressMessage:thread
  65. block:^(SignalRecipient *recipient) {
  66. SSKProtoContentBuilder *contentBuilder =
  67. [SSKProtoContent builder];
  68. return [[contentBuilder buildIgnoringErrors]
  69. serializedDataIgnoringErrors];
  70. }];
  71. }]];
  72. [items addObject:[OWSTableItem itemWithTitle:@"Send empty null message"
  73. actionBlock:^{
  74. [DebugUIStress sendStressMessage:thread
  75. block:^(SignalRecipient *recipient) {
  76. SSKProtoContentBuilder *contentBuilder =
  77. [SSKProtoContent builder];
  78. SSKProtoNullMessageBuilder *nullMessageBuilder =
  79. [SSKProtoNullMessage builder];
  80. contentBuilder.nullMessage =
  81. [nullMessageBuilder buildIgnoringErrors];
  82. return [[contentBuilder buildIgnoringErrors]
  83. serializedDataIgnoringErrors];
  84. }];
  85. }]];
  86. [items addObject:[OWSTableItem itemWithTitle:@"Send random null message"
  87. actionBlock:^{
  88. [DebugUIStress
  89. sendStressMessage:thread
  90. block:^(SignalRecipient *recipient) {
  91. SSKProtoContentBuilder *contentBuilder =
  92. [SSKProtoContent builder];
  93. SSKProtoNullMessageBuilder *nullMessageBuilder =
  94. [SSKProtoNullMessage builder];
  95. NSUInteger contentLength = arc4random_uniform(32);
  96. nullMessageBuilder.padding =
  97. [Cryptography generateRandomBytes:contentLength];
  98. contentBuilder.nullMessage =
  99. [nullMessageBuilder buildIgnoringErrors];
  100. return [[contentBuilder buildIgnoringErrors]
  101. serializedDataIgnoringErrors];
  102. }];
  103. }]];
  104. [items addObject:[OWSTableItem itemWithTitle:@"Send empty sync message"
  105. actionBlock:^{
  106. [DebugUIStress sendStressMessage:thread
  107. block:^(SignalRecipient *recipient) {
  108. SSKProtoContentBuilder *contentBuilder =
  109. [SSKProtoContent builder];
  110. SSKProtoSyncMessageBuilder *syncMessageBuilder =
  111. [SSKProtoSyncMessage builder];
  112. contentBuilder.syncMessage =
  113. [syncMessageBuilder buildIgnoringErrors];
  114. return [[contentBuilder buildIgnoringErrors]
  115. serializedDataIgnoringErrors];
  116. }];
  117. }]];
  118. [items addObject:[OWSTableItem itemWithTitle:@"Send empty sync sent message"
  119. actionBlock:^{
  120. [DebugUIStress sendStressMessage:thread
  121. block:^(SignalRecipient *recipient) {
  122. SSKProtoContentBuilder *contentBuilder =
  123. [SSKProtoContent builder];
  124. SSKProtoSyncMessageBuilder *syncMessageBuilder =
  125. [SSKProtoSyncMessage builder];
  126. SSKProtoSyncMessageSentBuilder *sentBuilder =
  127. [SSKProtoSyncMessageSent builder];
  128. syncMessageBuilder.sent =
  129. [sentBuilder buildIgnoringErrors];
  130. contentBuilder.syncMessage =
  131. [syncMessageBuilder buildIgnoringErrors];
  132. return [[contentBuilder buildIgnoringErrors]
  133. serializedDataIgnoringErrors];
  134. }];
  135. }]];
  136. [items addObject:[OWSTableItem itemWithTitle:@"Send whitespace text data message"
  137. actionBlock:^{
  138. [DebugUIStress
  139. sendStressMessage:thread
  140. block:^(SignalRecipient *recipient) {
  141. SSKProtoContentBuilder *contentBuilder =
  142. [SSKProtoContent builder];
  143. SSKProtoDataMessageBuilder *dataBuilder =
  144. [SSKProtoDataMessage builder];
  145. dataBuilder.body = @" ";
  146. [DebugUIStress ensureGroupOfDataBuilder:dataBuilder
  147. thread:thread];
  148. contentBuilder.dataMessage =
  149. [dataBuilder buildIgnoringErrors];
  150. return [[contentBuilder buildIgnoringErrors]
  151. serializedDataIgnoringErrors];
  152. }];
  153. }]];
  154. [items
  155. addObject:[OWSTableItem
  156. itemWithTitle:@"Send bad attachment data message"
  157. actionBlock:^{
  158. [DebugUIStress
  159. sendStressMessage:thread
  160. block:^(SignalRecipient *recipient) {
  161. SSKProtoContentBuilder *contentBuilder = [SSKProtoContent builder];
  162. SSKProtoDataMessageBuilder *dataBuilder = [SSKProtoDataMessage builder];
  163. SSKProtoAttachmentPointerBuilder *attachmentPointer =
  164. [SSKProtoAttachmentPointer
  165. builderWithId:arc4random_uniform(32) + 1];
  166. [attachmentPointer setContentType:@"1"];
  167. [attachmentPointer setSize:arc4random_uniform(32) + 1];
  168. [attachmentPointer setDigest:[Cryptography generateRandomBytes:1]];
  169. [attachmentPointer setFileName:@" "];
  170. [DebugUIStress ensureGroupOfDataBuilder:dataBuilder thread:thread];
  171. contentBuilder.dataMessage = [dataBuilder buildIgnoringErrors];
  172. return
  173. [[contentBuilder buildIgnoringErrors] serializedDataIgnoringErrors];
  174. }];
  175. }]];
  176. [items addObject:[OWSTableItem itemWithTitle:@"Send normal text data message"
  177. actionBlock:^{
  178. [DebugUIStress
  179. sendStressMessage:thread
  180. block:^(SignalRecipient *recipient) {
  181. SSKProtoContentBuilder *contentBuilder =
  182. [SSKProtoContent builder];
  183. SSKProtoDataMessageBuilder *dataBuilder =
  184. [SSKProtoDataMessage builder];
  185. dataBuilder.body = @"alice";
  186. [DebugUIStress ensureGroupOfDataBuilder:dataBuilder
  187. thread:thread];
  188. contentBuilder.dataMessage =
  189. [dataBuilder buildIgnoringErrors];
  190. return [[contentBuilder buildIgnoringErrors]
  191. serializedDataIgnoringErrors];
  192. }];
  193. }]];
  194. [items addObject:[OWSTableItem itemWithTitle:@"Send N text messages with same timestamp"
  195. actionBlock:^{
  196. uint64_t timestamp = [NSDate ows_millisecondTimeStamp];
  197. for (int i = 0; i < 3; i++) {
  198. [DebugUIStress
  199. sendStressMessage:thread
  200. timestamp:timestamp
  201. block:^(SignalRecipient *recipient) {
  202. SSKProtoContentBuilder *contentBuilder =
  203. [SSKProtoContent builder];
  204. SSKProtoDataMessageBuilder *dataBuilder =
  205. [SSKProtoDataMessage builder];
  206. dataBuilder.body = [NSString stringWithFormat:@"%@ %d",
  207. [NSUUID UUID].UUIDString,
  208. i];
  209. [DebugUIStress ensureGroupOfDataBuilder:dataBuilder
  210. thread:thread];
  211. contentBuilder.dataMessage =
  212. [dataBuilder buildIgnoringErrors];
  213. return [[contentBuilder buildIgnoringErrors]
  214. serializedDataIgnoringErrors];
  215. }];
  216. }
  217. }]];
  218. [items addObject:[OWSTableItem
  219. itemWithTitle:@"Send text message with current timestamp"
  220. actionBlock:^{
  221. uint64_t timestamp = [NSDate ows_millisecondTimeStamp];
  222. [DebugUIStress
  223. sendStressMessage:thread
  224. timestamp:timestamp
  225. block:^(SignalRecipient *recipient) {
  226. SSKProtoContentBuilder *contentBuilder = [SSKProtoContent builder];
  227. SSKProtoDataMessageBuilder *dataBuilder =
  228. [SSKProtoDataMessage builder];
  229. dataBuilder.body =
  230. [[NSUUID UUID].UUIDString stringByAppendingString:@" now"];
  231. [DebugUIStress ensureGroupOfDataBuilder:dataBuilder thread:thread];
  232. contentBuilder.dataMessage = [dataBuilder buildIgnoringErrors];
  233. return [[contentBuilder buildIgnoringErrors]
  234. serializedDataIgnoringErrors];
  235. }];
  236. }]];
  237. [items addObject:[OWSTableItem
  238. itemWithTitle:@"Send text message with future timestamp"
  239. actionBlock:^{
  240. uint64_t timestamp = [NSDate ows_millisecondTimeStamp];
  241. timestamp += kHourInMs;
  242. [DebugUIStress
  243. sendStressMessage:thread
  244. timestamp:timestamp
  245. block:^(SignalRecipient *recipient) {
  246. SSKProtoContentBuilder *contentBuilder = [SSKProtoContent builder];
  247. SSKProtoDataMessageBuilder *dataBuilder =
  248. [SSKProtoDataMessage builder];
  249. dataBuilder.body =
  250. [[NSUUID UUID].UUIDString stringByAppendingString:@" now"];
  251. [DebugUIStress ensureGroupOfDataBuilder:dataBuilder thread:thread];
  252. contentBuilder.dataMessage = [dataBuilder buildIgnoringErrors];
  253. return [[contentBuilder buildIgnoringErrors]
  254. serializedDataIgnoringErrors];
  255. }];
  256. }]];
  257. [items addObject:[OWSTableItem
  258. itemWithTitle:@"Send text message with past timestamp"
  259. actionBlock:^{
  260. uint64_t timestamp = [NSDate ows_millisecondTimeStamp];
  261. timestamp -= kHourInMs;
  262. [DebugUIStress
  263. sendStressMessage:thread
  264. timestamp:timestamp
  265. block:^(SignalRecipient *recipient) {
  266. SSKProtoContentBuilder *contentBuilder = [SSKProtoContent builder];
  267. SSKProtoDataMessageBuilder *dataBuilder =
  268. [SSKProtoDataMessage builder];
  269. dataBuilder.body =
  270. [[NSUUID UUID].UUIDString stringByAppendingString:@" now"];
  271. [DebugUIStress ensureGroupOfDataBuilder:dataBuilder thread:thread];
  272. contentBuilder.dataMessage = [dataBuilder buildIgnoringErrors];
  273. return [[contentBuilder buildIgnoringErrors]
  274. serializedDataIgnoringErrors];
  275. }];
  276. }]];
  277. [items addObject:[OWSTableItem itemWithTitle:@"Send N text messages with same timestamp"
  278. actionBlock:^{
  279. SSKProtoContentBuilder *contentBuilder = [SSKProtoContent builder];
  280. SSKProtoDataMessageBuilder *dataBuilder = [SSKProtoDataMessage builder];
  281. dataBuilder.body = @"alice";
  282. contentBuilder.dataMessage = [dataBuilder buildIgnoringErrors];
  283. [DebugUIStress ensureGroupOfDataBuilder:dataBuilder thread:thread];
  284. NSData *data =
  285. [[contentBuilder buildIgnoringErrors] serializedDataIgnoringErrors];
  286. uint64_t timestamp = [NSDate ows_millisecondTimeStamp];
  287. for (int i = 0; i < 3; i++) {
  288. [DebugUIStress sendStressMessage:thread
  289. timestamp:timestamp
  290. block:^(SignalRecipient *recipient) {
  291. return data;
  292. }];
  293. }
  294. }]];
  295. [items
  296. addObject:[OWSTableItem
  297. itemWithTitle:@"Send malformed sync sent message 1"
  298. actionBlock:^{
  299. [DebugUIStress
  300. sendStressMessage:thread
  301. block:^(SignalRecipient *recipient) {
  302. SSKProtoContentBuilder *contentBuilder = [SSKProtoContent builder];
  303. SSKProtoSyncMessageBuilder *syncMessageBuilder =
  304. [SSKProtoSyncMessage builder];
  305. SSKProtoSyncMessageSentBuilder *sentBuilder =
  306. [SSKProtoSyncMessageSent builder];
  307. sentBuilder.destinationE164 = @"abc";
  308. sentBuilder.timestamp = arc4random_uniform(32) + 1;
  309. SSKProtoDataMessageBuilder *dataBuilder = [SSKProtoDataMessage builder];
  310. sentBuilder.message = [dataBuilder buildIgnoringErrors];
  311. syncMessageBuilder.sent = [sentBuilder buildIgnoringErrors];
  312. contentBuilder.syncMessage = [syncMessageBuilder buildIgnoringErrors];
  313. return
  314. [[contentBuilder buildIgnoringErrors] serializedDataIgnoringErrors];
  315. }];
  316. }]];
  317. [items
  318. addObject:[OWSTableItem
  319. itemWithTitle:@"Send malformed sync sent message 2"
  320. actionBlock:^{
  321. [DebugUIStress
  322. sendStressMessage:thread
  323. block:^(SignalRecipient *recipient) {
  324. SSKProtoContentBuilder *contentBuilder = [SSKProtoContent builder];
  325. SSKProtoSyncMessageBuilder *syncMessageBuilder =
  326. [SSKProtoSyncMessage builder];
  327. SSKProtoSyncMessageSentBuilder *sentBuilder =
  328. [SSKProtoSyncMessageSent builder];
  329. sentBuilder.destinationE164 = @"abc";
  330. sentBuilder.timestamp = 0;
  331. SSKProtoDataMessageBuilder *dataBuilder = [SSKProtoDataMessage builder];
  332. sentBuilder.message = [dataBuilder buildIgnoringErrors];
  333. syncMessageBuilder.sent = [sentBuilder buildIgnoringErrors];
  334. contentBuilder.syncMessage = [syncMessageBuilder buildIgnoringErrors];
  335. return
  336. [[contentBuilder buildIgnoringErrors] serializedDataIgnoringErrors];
  337. }];
  338. }]];
  339. [items
  340. addObject:[OWSTableItem
  341. itemWithTitle:@"Send malformed sync sent message 3"
  342. actionBlock:^{
  343. [DebugUIStress
  344. sendStressMessage:thread
  345. block:^(SignalRecipient *recipient) {
  346. SSKProtoContentBuilder *contentBuilder = [SSKProtoContent builder];
  347. SSKProtoSyncMessageBuilder *syncMessageBuilder =
  348. [SSKProtoSyncMessage builder];
  349. SSKProtoSyncMessageSentBuilder *sentBuilder =
  350. [SSKProtoSyncMessageSent builder];
  351. sentBuilder.destinationE164 = @"abc";
  352. sentBuilder.timestamp = 0;
  353. SSKProtoDataMessageBuilder *dataBuilder = [SSKProtoDataMessage builder];
  354. dataBuilder.body = @" ";
  355. sentBuilder.message = [dataBuilder buildIgnoringErrors];
  356. syncMessageBuilder.sent = [sentBuilder buildIgnoringErrors];
  357. contentBuilder.syncMessage = [syncMessageBuilder buildIgnoringErrors];
  358. return
  359. [[contentBuilder buildIgnoringErrors] serializedDataIgnoringErrors];
  360. }];
  361. }]];
  362. [items
  363. addObject:[OWSTableItem
  364. itemWithTitle:@"Send malformed sync sent message 4"
  365. actionBlock:^{
  366. [DebugUIStress
  367. sendStressMessage:thread
  368. block:^(SignalRecipient *recipient) {
  369. SSKProtoContentBuilder *contentBuilder = [SSKProtoContent builder];
  370. SSKProtoSyncMessageBuilder *syncMessageBuilder =
  371. [SSKProtoSyncMessage builder];
  372. SSKProtoSyncMessageSentBuilder *sentBuilder =
  373. [SSKProtoSyncMessageSent builder];
  374. sentBuilder.destinationE164 = @"abc";
  375. sentBuilder.timestamp = 0;
  376. SSKProtoDataMessageBuilder *dataBuilder = [SSKProtoDataMessage builder];
  377. dataBuilder.body = @" ";
  378. SSKProtoGroupContextBuilder *groupBuilder = [SSKProtoGroupContext
  379. builderWithId:[Cryptography generateRandomBytes:1]];
  380. [groupBuilder setType:SSKProtoGroupContextTypeDeliver];
  381. dataBuilder.group = [groupBuilder buildIgnoringErrors];
  382. sentBuilder.message = [dataBuilder buildIgnoringErrors];
  383. syncMessageBuilder.sent = [sentBuilder buildIgnoringErrors];
  384. contentBuilder.syncMessage = [syncMessageBuilder buildIgnoringErrors];
  385. return
  386. [[contentBuilder buildIgnoringErrors] serializedDataIgnoringErrors];
  387. }];
  388. }]];
  389. [items
  390. addObject:[OWSTableItem
  391. itemWithTitle:@"Send malformed sync sent message 5"
  392. actionBlock:^{
  393. [DebugUIStress
  394. sendStressMessage:thread
  395. block:^(SignalRecipient *recipient) {
  396. SSKProtoContentBuilder *contentBuilder = [SSKProtoContent builder];
  397. SSKProtoSyncMessageBuilder *syncMessageBuilder =
  398. [SSKProtoSyncMessage builder];
  399. SSKProtoSyncMessageSentBuilder *sentBuilder =
  400. [SSKProtoSyncMessageSent builder];
  401. sentBuilder.destinationE164 = @"abc";
  402. sentBuilder.timestamp = 0;
  403. SSKProtoDataMessageBuilder *dataBuilder = [SSKProtoDataMessage builder];
  404. dataBuilder.body = @" ";
  405. SSKProtoGroupContextBuilder *groupBuilder = [SSKProtoGroupContext
  406. builderWithId:[Cryptography generateRandomBytes:1]];
  407. [groupBuilder setType:SSKProtoGroupContextTypeDeliver];
  408. dataBuilder.group = [groupBuilder buildIgnoringErrors];
  409. sentBuilder.message = [dataBuilder buildIgnoringErrors];
  410. syncMessageBuilder.sent = [sentBuilder buildIgnoringErrors];
  411. contentBuilder.syncMessage = [syncMessageBuilder buildIgnoringErrors];
  412. return
  413. [[contentBuilder buildIgnoringErrors] serializedDataIgnoringErrors];
  414. }];
  415. }]];
  416. [items addObject:[OWSTableItem itemWithTitle:@"Send empty sync sent message 6"
  417. actionBlock:^{
  418. [DebugUIStress sendStressMessage:thread
  419. block:^(SignalRecipient *recipient) {
  420. SSKProtoContentBuilder *contentBuilder =
  421. [SSKProtoContent builder];
  422. SSKProtoSyncMessageBuilder *syncMessageBuilder =
  423. [SSKProtoSyncMessage builder];
  424. SSKProtoSyncMessageSentBuilder *sentBuilder =
  425. [SSKProtoSyncMessageSent builder];
  426. sentBuilder.destinationE164 = @"abc";
  427. syncMessageBuilder.sent =
  428. [sentBuilder buildIgnoringErrors];
  429. contentBuilder.syncMessage =
  430. [syncMessageBuilder buildIgnoringErrors];
  431. return [[contentBuilder buildIgnoringErrors]
  432. serializedDataIgnoringErrors];
  433. }];
  434. }]];
  435. if ([thread isKindOfClass:[TSGroupThread class]]) {
  436. TSGroupThread *groupThread = (TSGroupThread *)thread;
  437. [items addObject:[OWSTableItem itemWithTitle:@"Hallucinate twin group"
  438. actionBlock:^{
  439. [DebugUIStress hallucinateTwinGroup:groupThread];
  440. }]];
  441. }
  442. [items addObject:[OWSTableItem itemWithTitle:@"Make group w. unregistered users"
  443. actionBlock:^{
  444. [DebugUIStress makeUnregisteredGroup];
  445. }]];
  446. return [OWSTableSection sectionWithTitle:self.name items:items];
  447. }
  448. + (void)ensureGroupOfDataBuilder:(SSKProtoDataMessageBuilder *)dataBuilder thread:(TSThread *)thread
  449. {
  450. OWSAssertDebug(dataBuilder);
  451. OWSAssertDebug(thread);
  452. if (![thread isKindOfClass:[TSGroupThread class]]) {
  453. return;
  454. }
  455. TSGroupThread *groupThread = (TSGroupThread *)thread;
  456. SSKProtoGroupContextBuilder *groupBuilder = [SSKProtoGroupContext builderWithId:groupThread.groupModel.groupId];
  457. [groupBuilder setType:SSKProtoGroupContextTypeDeliver];
  458. [groupBuilder setId:groupThread.groupModel.groupId];
  459. [dataBuilder setGroup:groupBuilder.buildIgnoringErrors];
  460. }
  461. + (void)sendStressMessage:(TSOutgoingMessage *)message
  462. {
  463. OWSAssertDebug(message);
  464. [self.databaseStorage writeWithBlock:^(SDSAnyWriteTransaction *transaction) {
  465. [self.messageSenderJobQueue addMessage:message.asPreparer transaction:transaction];
  466. }];
  467. }
  468. + (void)sendStressMessage:(TSThread *)thread
  469. block:(DynamicOutgoingMessageBlock)block
  470. {
  471. OWSAssertDebug(thread);
  472. OWSAssertDebug(block);
  473. OWSDynamicOutgoingMessage *message =
  474. [[OWSDynamicOutgoingMessage alloc] initWithPlainTextDataBlock:block thread:thread];
  475. [self sendStressMessage:message];
  476. }
  477. + (void)sendStressMessage:(TSThread *)thread timestamp:(uint64_t)timestamp block:(DynamicOutgoingMessageBlock)block
  478. {
  479. OWSAssertDebug(thread);
  480. OWSAssertDebug(block);
  481. OWSDynamicOutgoingMessage *message =
  482. [[OWSDynamicOutgoingMessage alloc] initWithPlainTextDataBlock:block timestamp:timestamp thread:thread];
  483. [self sendStressMessage:message];
  484. }
  485. // Creates a new group (by cloning the current group) without informing the,
  486. // other members. This can be used to test "group info requests", etc.
  487. + (void)hallucinateTwinGroup:(TSGroupThread *)groupThread
  488. {
  489. NSString *groupName = [groupThread.groupModel.groupName stringByAppendingString:@" Copy"];
  490. [GroupManager createGroupObjcWithMembers:groupThread.groupModel.groupMembers
  491. groupId:nil
  492. name:groupName
  493. avatarData:groupThread.groupModel.groupAvatarData
  494. success:^(TSGroupThread * thread) {
  495. [SignalApp.sharedApp presentConversationForThread:thread animated:YES];
  496. } failure:^(NSError * error) {
  497. OWSFailDebug(@"Error: %@", error);
  498. }];
  499. }
  500. + (void)makeUnregisteredGroup
  501. {
  502. NSMutableArray<SignalServiceAddress *> *recipientAddresses = [NSMutableArray new];
  503. for (int i = 0; i < 3; i++) {
  504. NSMutableString *recipientNumber = [@"+1999" mutableCopy];
  505. for (int j = 0; j < 3; j++) {
  506. uint32_t digit = arc4random_uniform(10);
  507. [recipientNumber appendFormat:@"%d", (int)digit];
  508. }
  509. [recipientAddresses addObject:[[SignalServiceAddress alloc] initWithUuid:[NSUUID UUID]
  510. phoneNumber:recipientNumber]];
  511. }
  512. [recipientAddresses addObject:self.tsAccountManager.localAddress];
  513. if (SSKFeatureFlags.allowUUIDOnlyContacts) {
  514. for (int i = 0; i < 3; i++) {
  515. [recipientAddresses addObject:[[SignalServiceAddress alloc] initWithUuid:[NSUUID UUID] phoneNumber:nil]];
  516. }
  517. }
  518. [GroupManager createGroupObjcWithMembers:recipientAddresses
  519. groupId:nil
  520. name:NSUUID.UUID.UUIDString
  521. avatarData:nil
  522. success:^(TSGroupThread * thread) {
  523. [SignalApp.sharedApp presentConversationForThread:thread animated:YES];
  524. } failure:^(NSError * error) {
  525. OWSFailDebug(@"Error: %@", error);
  526. }];
  527. }
  528. @end
  529. NS_ASSUME_NONNULL_END
  530. #endif