Skip to content

Commit 0ffc9ac

Browse files
authored
Support IAM caps (#442)
* initial commit * small fixes and unit tests * fix time to use seconds * clean up code * fix force content update * fix indentation and formatting * LPLog added for suppressed message
1 parent f93e9ab commit 0ffc9ac

File tree

19 files changed

+680
-16
lines changed

19 files changed

+680
-16
lines changed

Example/Leanplum-SDK.xcodeproj/project.pbxproj

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,15 @@
127127
C9AC35B7266D624A008337F2 /* secured_vars_no_sign_response.json in Resources */ = {isa = PBXBuildFile; fileRef = C9AC35B5266D624A008337F2 /* secured_vars_no_sign_response.json */; };
128128
C9AC35BB266D62A1008337F2 /* secured_vars_empty_response.json in Resources */ = {isa = PBXBuildFile; fileRef = C9AC35BA266D62A1008337F2 /* secured_vars_empty_response.json */; };
129129
C9AC35BC266D62A1008337F2 /* secured_vars_empty_response.json in Resources */ = {isa = PBXBuildFile; fileRef = C9AC35BA266D62A1008337F2 /* secured_vars_empty_response.json */; };
130+
C9B092532684FB32008B3268 /* LPLocalCapsTest.m in Sources */ = {isa = PBXBuildFile; fileRef = C9B092522684FB32008B3268 /* LPLocalCapsTest.m */; };
131+
C9B092552684FCFF008B3268 /* local_caps_response.json in Resources */ = {isa = PBXBuildFile; fileRef = C9B092542684FCFE008B3268 /* local_caps_response.json */; };
132+
C9B092562684FCFF008B3268 /* local_caps_response.json in Resources */ = {isa = PBXBuildFile; fileRef = C9B092542684FCFE008B3268 /* local_caps_response.json */; };
133+
C9B092582684FFDC008B3268 /* local_caps_day_response.json in Resources */ = {isa = PBXBuildFile; fileRef = C9B092572684FFDC008B3268 /* local_caps_day_response.json */; };
134+
C9B092592684FFDC008B3268 /* local_caps_day_response.json in Resources */ = {isa = PBXBuildFile; fileRef = C9B092572684FFDC008B3268 /* local_caps_day_response.json */; };
135+
C9B0925B2684FFFA008B3268 /* local_caps_session_response.json in Resources */ = {isa = PBXBuildFile; fileRef = C9B0925A2684FFFA008B3268 /* local_caps_session_response.json */; };
136+
C9B0925C2684FFFA008B3268 /* local_caps_session_response.json in Resources */ = {isa = PBXBuildFile; fileRef = C9B0925A2684FFFA008B3268 /* local_caps_session_response.json */; };
137+
C9B0925E26850011008B3268 /* local_caps_week_response.json in Resources */ = {isa = PBXBuildFile; fileRef = C9B0925D26850011008B3268 /* local_caps_week_response.json */; };
138+
C9B0925F26850011008B3268 /* local_caps_week_response.json in Resources */ = {isa = PBXBuildFile; fileRef = C9B0925D26850011008B3268 /* local_caps_week_response.json */; };
130139
C9C0C87025898CE900346291 /* LPRequestBatchTest.m in Sources */ = {isa = PBXBuildFile; fileRef = C9C0C86F25898CE900346291 /* LPRequestBatchTest.m */; };
131140
C9C0C87425898D0100346291 /* LPRequestSenderTimerTest.m in Sources */ = {isa = PBXBuildFile; fileRef = C9C0C87325898D0100346291 /* LPRequestSenderTimerTest.m */; };
132141
E773031E24AB871E00EDF983 /* Leanplum-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = E773031D24AB871E00EDF983 /* Leanplum-Info.plist */; };
@@ -260,6 +269,11 @@
260269
C9AC35B0266D620C008337F2 /* secured_vars_response.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = secured_vars_response.json; sourceTree = "<group>"; };
261270
C9AC35B5266D624A008337F2 /* secured_vars_no_sign_response.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = secured_vars_no_sign_response.json; sourceTree = "<group>"; };
262271
C9AC35BA266D62A1008337F2 /* secured_vars_empty_response.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = secured_vars_empty_response.json; sourceTree = "<group>"; };
272+
C9B092522684FB32008B3268 /* LPLocalCapsTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LPLocalCapsTest.m; sourceTree = "<group>"; };
273+
C9B092542684FCFE008B3268 /* local_caps_response.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = local_caps_response.json; sourceTree = "<group>"; };
274+
C9B092572684FFDC008B3268 /* local_caps_day_response.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = local_caps_day_response.json; sourceTree = "<group>"; };
275+
C9B0925A2684FFFA008B3268 /* local_caps_session_response.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = local_caps_session_response.json; sourceTree = "<group>"; };
276+
C9B0925D26850011008B3268 /* local_caps_week_response.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = local_caps_week_response.json; sourceTree = "<group>"; };
263277
C9C0C86F25898CE900346291 /* LPRequestBatchTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LPRequestBatchTest.m; sourceTree = "<group>"; };
264278
C9C0C87325898D0100346291 /* LPRequestSenderTimerTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LPRequestSenderTimerTest.m; sourceTree = "<group>"; };
265279
D838E08C49B78EF6BAA262C1 /* Pods_Leanplum_SDK_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Leanplum_SDK_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -327,6 +341,7 @@
327341
9E53F6E22474387B0097955F /* LPPushNotificationsHandlerTest.m */,
328342
6A7815E224F6A89C004F3DC7 /* LPDeferMessageManagerTest.m */,
329343
C9AC35AC266D6185008337F2 /* LPSecuredVarsTest.m */,
344+
C9B092522684FB32008B3268 /* LPLocalCapsTest.m */,
330345
);
331346
path = Classes;
332347
sourceTree = "<group>";
@@ -403,6 +418,10 @@
403418
C9AC35B0266D620C008337F2 /* secured_vars_response.json */,
404419
C9AC35B5266D624A008337F2 /* secured_vars_no_sign_response.json */,
405420
C9AC35BA266D62A1008337F2 /* secured_vars_empty_response.json */,
421+
C9B092542684FCFE008B3268 /* local_caps_response.json */,
422+
C9B092572684FFDC008B3268 /* local_caps_day_response.json */,
423+
C9B0925A2684FFFA008B3268 /* local_caps_session_response.json */,
424+
C9B0925D26850011008B3268 /* local_caps_week_response.json */,
406425
);
407426
path = Responses;
408427
sourceTree = "<group>";
@@ -666,6 +685,7 @@
666685
873B8AEB1B1F5CCA007FD442 /* Main.storyboard in Resources */,
667686
07E5C8F11F052DD000A4B092 /* NoPriorities.json in Resources */,
668687
07E5C8DE1F052DC400A4B092 /* newsfeed_response.json in Resources */,
688+
C9B0925E26850011008B3268 /* local_caps_week_response.json in Resources */,
669689
07E5C8F61F052DD000A4B092 /* TiedPriorities2.json in Resources */,
670690
07E5C8DF1F052DC400A4B092 /* registration_response.json in Resources */,
671691
9CD04D951F8EE7E30033AB4A /* variables_with_newsfeed_response.json in Resources */,
@@ -689,12 +709,15 @@
689709
07E5C8DD1F052DC400A4B092 /* complex_start_response.json in Resources */,
690710
07E5C8EE1F052DD000A4B092 /* DifferentPriorities1.json in Resources */,
691711
07E5C8ED1F052DD000A4B092 /* ChainedMessage.json in Resources */,
712+
C9B0925B2684FFFA008B3268 /* local_caps_session_response.json in Resources */,
692713
6003F598195388D20070C39A /* InfoPlist.strings in Resources */,
714+
C9B092552684FCFF008B3268 /* local_caps_response.json in Resources */,
693715
07E5C8E31F052DC400A4B092 /* state_response.json in Resources */,
694716
07E5C8EF1F052DD000A4B092 /* DifferentPriorities2.json in Resources */,
695717
07E5C8E61F052DC400A4B092 /* variables_response.json in Resources */,
696718
07E5C8E11F052DC400A4B092 /* simple_start_response.json in Resources */,
697719
C9AC35BB266D62A1008337F2 /* secured_vars_empty_response.json in Resources */,
720+
C9B092582684FFDC008B3268 /* local_caps_day_response.json in Resources */,
698721
B449EB2A21F27AB2005C93B6 /* TiedPrioritiesDifferentDelay.json in Resources */,
699722
07E5C8F41F052DD000A4B092 /* SingleMessage.json in Resources */,
700723
07E5C8EC1F052DCC00A4B092 /* test.pdf in Resources */,
@@ -710,12 +733,15 @@
710733
07E5C8C31F052B7800A4B092 /* action_response.json in Resources */,
711734
A8EEA1AC20E44B0B00FF9A4D /* start_with_variant_debug_info_response.json in Resources */,
712735
07E5C8D31F052B7800A4B092 /* DifferentPriorities2.json in Resources */,
736+
C9B0925F26850011008B3268 /* local_caps_week_response.json in Resources */,
713737
07E5C8D41F052B7800A4B092 /* DifferentPrioritiesWithMissingValues.json in Resources */,
714738
07E5C8C71F052B7800A4B092 /* malformed_track_event_response.json in Resources */,
715739
07E5C8BF1F052B7800A4B092 /* GoldIcon.png in Resources */,
740+
C9B092592684FFDC008B3268 /* local_caps_day_response.json in Resources */,
716741
07E5C8D21F052B7800A4B092 /* DifferentPriorities1.json in Resources */,
717742
07E5C8C91F052B7800A4B092 /* registration_response.json in Resources */,
718743
9CB691DE1F15FFF5002D83D8 /* batch_response.json in Resources */,
744+
C9B092562684FCFF008B3268 /* local_caps_response.json in Resources */,
719745
073DF05C22280C1A00CC96DF /* variants_response.json in Resources */,
720746
07E5C8DA1F052B7800A4B092 /* TiedPriorities2.json in Resources */,
721747
6003F5BA195388D20070C39A /* InfoPlist.strings in Resources */,
@@ -734,6 +760,7 @@
734760
07E5C8CD1F052B7800A4B092 /* state_response.json in Resources */,
735761
07E5C8D91F052B7800A4B092 /* TiedPriorities1.json in Resources */,
736762
07E5C8C81F052B7800A4B092 /* newsfeed_response.json in Resources */,
763+
C9B0925C2684FFFA008B3268 /* local_caps_session_response.json in Resources */,
737764
07E5C8C61F052B7800A4B092 /* malformed_simple_start_response.json in Resources */,
738765
07E5C8CC1F052B7800A4B092 /* start_variables_response.json in Resources */,
739766
07E5C8C51F052B7800A4B092 /* complex_start_response.json in Resources */,
@@ -874,6 +901,7 @@
874901
A84527FD215C3035001FA20D /* LPRequestTest.m in Sources */,
875902
07E5C8AC1F052B7800A4B092 /* LPAppIconManagerTest.m in Sources */,
876903
9EF00D3A2448DE3E0094CA89 /* LPOpenUrlMessageTemplateTest.m in Sources */,
904+
C9B092532684FB32008B3268 /* LPLocalCapsTest.m in Sources */,
877905
A824579B2411CB600044B1EB /* LPRichInterstitialMessageSnapshotTest.m in Sources */,
878906
9E53F6DF2474363D0097955F /* LPNotificationsManagerTest.m in Sources */,
879907
07E5C8BA1F052B7800A4B092 /* LPInboxTest.m in Sources */,

Example/Tests/Classes/LPActionContextTest.m

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ - (void)setUp {
3737
[[LPVarCache sharedCache] applyVariableDiffs:nil
3838
messages:nil
3939
variants:nil
40+
localCaps:nil
4041
regions:nil
4142
variantDebugInfo:nil
4243
varsJson:nil
@@ -62,6 +63,7 @@ - (void)test_setProperArgs_messageWithArgs {
6263
[[LPVarCache sharedCache] applyVariableDiffs:nil
6364
messages:messages
6465
variants:nil
66+
localCaps:nil
6567
regions:nil
6668
variantDebugInfo:nil
6769
varsJson:nil
@@ -87,6 +89,7 @@ - (void)test_setProperArgs_messageWithNilArgs {
8789
[[LPVarCache sharedCache] applyVariableDiffs:nil
8890
messages:messages
8991
variants:nil
92+
localCaps:nil
9093
regions:nil
9194
variantDebugInfo:nil
9295
varsJson:nil
@@ -110,6 +113,7 @@ - (void)test_setProperArgs_noMessage {
110113
[[LPVarCache sharedCache] applyVariableDiffs:nil
111114
messages:messages
112115
variants:nil
116+
localCaps:nil
113117
regions:nil
114118
variantDebugInfo:nil
115119
varsJson:nil

Example/Tests/Classes/LPActionManagerTest.m

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@
3535
#import "LPUIAlert.h"
3636
#import "LPOperationQueue.h"
3737

38+
@interface LPActionManager (UnitTest)
39+
40+
@end
41+
3842
@interface LPActionManagerTest : XCTestCase
3943

4044
@end
@@ -221,6 +225,157 @@ - (void)test_active_period_true
221225

222226
}
223227

228+
- (void)testShouldSuppressMessagesSessionLimit
229+
{
230+
id<HTTPStubsDescriptor> startStub = [HTTPStubs stubRequestsPassingTest:
231+
^BOOL(NSURLRequest * _Nonnull request) {
232+
return [request.URL.host isEqualToString:API_HOST];
233+
} withStubResponse:^HTTPStubsResponse * _Nonnull(NSURLRequest * _Nonnull request) {
234+
NSString *response_file = OHPathForFile(@"local_caps_session_response.json", self.class);
235+
return [HTTPStubsResponse responseWithFileAtPath:response_file statusCode:200
236+
headers:@{@"Content-Type":@"application/json"}];
237+
}];
238+
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
239+
[Leanplum startWithResponseHandler:^(BOOL success) {
240+
[HTTPStubs removeStub:startStub];
241+
if (success) {
242+
dispatch_semaphore_signal(semaphore);
243+
}
244+
245+
}];
246+
long timedOut = dispatch_semaphore_wait(semaphore, [LeanplumHelper default_dispatch_time]);
247+
if (timedOut > 0) {
248+
NSLog(@"test failed");
249+
XCTFail(@"timed out");
250+
}
251+
252+
for (int i = 1; i<=5; i++) {
253+
NSString *prefix = [NSString stringWithFormat:LEANPLUM_DEFAULTS_MESSAGE_IMPRESSION_OCCURRENCES_KEY, @""];
254+
NSString *key = [NSString stringWithFormat:@"%@message#%d", prefix, i];
255+
[[NSUserDefaults standardUserDefaults] removeObjectForKey:key];
256+
}
257+
258+
[[LPActionManager sharedManager] recordMessageImpression:@"message#1"];
259+
[[LPActionManager sharedManager] recordMessageImpression:@"message#2"];
260+
XCTAssertFalse([[LPActionManager sharedManager] shouldSuppressMessages]);
261+
262+
[[LPActionManager sharedManager] recordMessageImpression:@"message#3"];
263+
[[LPActionManager sharedManager] recordMessageImpression:@"message#4"];
264+
XCTAssertFalse([[LPActionManager sharedManager] shouldSuppressMessages]);
265+
266+
[[LPActionManager sharedManager] recordMessageImpression:@"message#5"];
267+
XCTAssertTrue([[LPActionManager sharedManager] shouldSuppressMessages]);
268+
}
269+
270+
- (void)testShouldSuppressMessagesDayLimit
271+
{
272+
id<HTTPStubsDescriptor> startStub = [HTTPStubs stubRequestsPassingTest:
273+
^BOOL(NSURLRequest * _Nonnull request) {
274+
return [request.URL.host isEqualToString:API_HOST];
275+
} withStubResponse:^HTTPStubsResponse * _Nonnull(NSURLRequest * _Nonnull request) {
276+
NSString *response_file = OHPathForFile(@"local_caps_day_response.json", self.class);
277+
return [HTTPStubsResponse responseWithFileAtPath:response_file statusCode:200
278+
headers:@{@"Content-Type":@"application/json"}];
279+
}];
280+
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
281+
[Leanplum startWithResponseHandler:^(BOOL success) {
282+
[HTTPStubs removeStub:startStub];
283+
if (success) {
284+
dispatch_semaphore_signal(semaphore);
285+
}
286+
287+
}];
288+
long timedOut = dispatch_semaphore_wait(semaphore, [LeanplumHelper default_dispatch_time]);
289+
if (timedOut > 0) {
290+
NSLog(@"test failed");
291+
XCTFail(@"timed out");
292+
}
293+
for (int i = 1; i<=5; i++) {
294+
NSString *prefix = [NSString stringWithFormat:LEANPLUM_DEFAULTS_MESSAGE_IMPRESSION_OCCURRENCES_KEY, @""];
295+
NSString *key = [NSString stringWithFormat:@"%@message#%d", prefix, i];
296+
[[NSUserDefaults standardUserDefaults] removeObjectForKey:key];
297+
}
298+
299+
[[LPActionManager sharedManager] recordMessageImpression:@"message#1"];
300+
[[LPActionManager sharedManager] recordMessageImpression:@"message#1"];
301+
[[LPActionManager sharedManager] recordMessageImpression:@"message#1"];
302+
[[LPActionManager sharedManager] recordMessageImpression:@"message#1"];
303+
[[LPActionManager sharedManager] recordMessageImpression:@"message#1"];
304+
XCTAssertFalse([[LPActionManager sharedManager] shouldSuppressMessages]);
305+
306+
[[LPActionManager sharedManager] recordMessageImpression:@"message#2"];
307+
[[LPActionManager sharedManager] recordMessageImpression:@"message#2"];
308+
[[LPActionManager sharedManager] recordMessageImpression:@"message#2"];
309+
[[LPActionManager sharedManager] recordMessageImpression:@"message#2"];
310+
[[LPActionManager sharedManager] recordMessageImpression:@"message#2"];
311+
XCTAssertFalse([[LPActionManager sharedManager] shouldSuppressMessages]);
312+
313+
[[LPActionManager sharedManager] recordMessageImpression:@"message#3"];
314+
[[LPActionManager sharedManager] recordMessageImpression:@"message#3"];
315+
[[LPActionManager sharedManager] recordMessageImpression:@"message#3"];
316+
[[LPActionManager sharedManager] recordMessageImpression:@"message#3"];
317+
[[LPActionManager sharedManager] recordMessageImpression:@"message#3"];
318+
XCTAssertFalse([[LPActionManager sharedManager] shouldSuppressMessages]);
319+
320+
[[LPActionManager sharedManager] recordMessageImpression:@"message#4"];
321+
[[LPActionManager sharedManager] recordMessageImpression:@"message#4"];
322+
[[LPActionManager sharedManager] recordMessageImpression:@"message#4"];
323+
[[LPActionManager sharedManager] recordMessageImpression:@"message#4"];
324+
[[LPActionManager sharedManager] recordMessageImpression:@"message#4"];
325+
XCTAssertFalse([[LPActionManager sharedManager] shouldSuppressMessages]);
326+
327+
[[LPActionManager sharedManager] recordMessageImpression:@"message#5"];
328+
[[LPActionManager sharedManager] recordMessageImpression:@"message#5"];
329+
[[LPActionManager sharedManager] recordMessageImpression:@"message#5"];
330+
[[LPActionManager sharedManager] recordMessageImpression:@"message#5"];
331+
XCTAssertFalse([[LPActionManager sharedManager] shouldSuppressMessages]);
332+
333+
[[LPActionManager sharedManager] recordMessageImpression:@"message#5"];
334+
XCTAssertTrue([[LPActionManager sharedManager] shouldSuppressMessages]);
335+
}
336+
337+
- (void)testShouldSuppressMessagesWeekLimit
338+
{
339+
id<HTTPStubsDescriptor> startStub = [HTTPStubs stubRequestsPassingTest:
340+
^BOOL(NSURLRequest * _Nonnull request) {
341+
return [request.URL.host isEqualToString:API_HOST];
342+
} withStubResponse:^HTTPStubsResponse * _Nonnull(NSURLRequest * _Nonnull request) {
343+
NSString *response_file = OHPathForFile(@"local_caps_week_response.json", self.class);
344+
return [HTTPStubsResponse responseWithFileAtPath:response_file statusCode:200
345+
headers:@{@"Content-Type":@"application/json"}];
346+
}];
347+
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
348+
[Leanplum startWithResponseHandler:^(BOOL success) {
349+
[HTTPStubs removeStub:startStub];
350+
if (success) {
351+
dispatch_semaphore_signal(semaphore);
352+
}
353+
354+
}];
355+
long timedOut = dispatch_semaphore_wait(semaphore, [LeanplumHelper default_dispatch_time]);
356+
if (timedOut > 0) {
357+
NSLog(@"test failed");
358+
XCTFail(@"timed out");
359+
}
360+
for (int i = 1; i<=5; i++) {
361+
NSString *prefix = [NSString stringWithFormat:LEANPLUM_DEFAULTS_MESSAGE_IMPRESSION_OCCURRENCES_KEY, @""];
362+
NSString *key = [NSString stringWithFormat:@"%@message#%d", prefix, i];
363+
[[NSUserDefaults standardUserDefaults] removeObjectForKey:key];
364+
}
365+
366+
for (int i = 1; i<=5; i++) {
367+
NSString *messageId = [NSString stringWithFormat:@"message#%d", i];
368+
for (int j = 0; j < 20; j++) {
369+
[[LPActionManager sharedManager] recordMessageImpression:messageId];
370+
}
371+
if (i == 5) {
372+
XCTAssertTrue([[LPActionManager sharedManager] shouldSuppressMessages]);
373+
} else {
374+
XCTAssertFalse([[LPActionManager sharedManager] shouldSuppressMessages]);
375+
}
376+
}
377+
}
378+
224379
#pragma mark Helpers
225380

226381
-(NSDictionary *)messageConfigInActivePeriod:(BOOL)inActivePeriod

0 commit comments

Comments
 (0)