diff --git a/.github/workflows/release-package.yml b/.github/workflows/release-package.yml index 5b606dd..8685083 100644 --- a/.github/workflows/release-package.yml +++ b/.github/workflows/release-package.yml @@ -24,7 +24,7 @@ jobs: - name: Build run: | # Add commands to build and test your package - xcodebuild -workspace Contentstack.xcworkspace -scheme 'Contentstack' -destination 'platform=iOS Simulator,name=iPhone 13 Pro' + xcodebuild -workspace Contentstack.xcworkspace -scheme 'Contentstack' -destination 'platform=iOS Simulator,name=iPhone 15' - name: CocoaPods trunk push run: pod trunk push --allow-warnings diff --git a/.github/workflows/sca-scan.yml b/.github/workflows/sca-scan.yml deleted file mode 100644 index cb54aad..0000000 --- a/.github/workflows/sca-scan.yml +++ /dev/null @@ -1,14 +0,0 @@ -name: Source Composition Analysis Scan -on: - pull_request: - types: [opened, synchronize, reopened] -jobs: - security-sca: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@master - - uses: snyk/actions/setup@master - - name: Run Snyk to check for vulnerabilities - run: snyk test --all-projects --fail-on=all - env: - SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} \ No newline at end of file diff --git a/.talismanrc b/.talismanrc index 9fbcfe9..9dd8a3f 100644 --- a/.talismanrc +++ b/.talismanrc @@ -1,4 +1,8 @@ fileignoreconfig: - filename: Contentstack.xcodeproj/project.pbxproj - checksum: 331c4ff2e540e9495ff2a0d030ddd7f7c2eda077cb0b1a58c67fc2312b53658e -version: "" \ No newline at end of file + checksum: 10cb4bc5ca755f7392309a88cd6df510a45f8c527ea2f8edc71e1ae1fda60941 +- filename: .github/workflows/sast-scan.yml + checksum: 5554abc81d130557f52d64d253c3a23b41fcf0642a9c599131b2c185665ce581 +- filename: PrivacyInfo.xcprivacy + checksum: 7697fa6a0a5e0600d35d4678ffff9ef14c5dff5dc1613d37968de7ded3ff1fd0 +version: "" diff --git a/Contentstack.podspec b/Contentstack.podspec index 79ca369..961aba1 100644 --- a/Contentstack.podspec +++ b/Contentstack.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'Contentstack' -s.version = '3.12.3' +s.version = '3.13.0' s.summary = 'Contentstack is a headless CMS with an API-first approach that puts content at the centre.' s.description = <<-DESC @@ -12,7 +12,7 @@ s.homepage = 'https://www.contentstack.com/' s.license = { :type => 'Commercial',:text => 'See https://www.contentstack.com/'} s.author = { 'Contentstack' => 'support@contentstack.io' } -s.source = { :git => 'https://github.com/contentstack/contentstack-ios.git', :tag => 'v3.12.3' } +s.source = { :git => 'https://github.com/contentstack/contentstack-ios.git', :tag => 'v3.13.0' } s.social_media_url = 'https://twitter.com/Contentstack' s.ios.deployment_target = '11.0' diff --git a/Contentstack.xcodeproj/project.pbxproj b/Contentstack.xcodeproj/project.pbxproj index 76834ff..5221e08 100644 --- a/Contentstack.xcodeproj/project.pbxproj +++ b/Contentstack.xcodeproj/project.pbxproj @@ -95,6 +95,8 @@ 23A53F501E277BBE001DBE35 /* NSObject+Extensions.m in Sources */ = {isa = PBXBuildFile; fileRef = 23A53F331E276BA5001DBE35 /* NSObject+Extensions.m */; }; 23A53F5A1E277CD3001DBE35 /* Contentstack.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 230B38C01C16E98B00444A14 /* Contentstack.framework */; }; 23B6F12A1B5662EE00A9E983 /* ISO8601DateFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = 23B6F1281B5662EE00A9E983 /* ISO8601DateFormatter.m */; }; + 4714B7D42C5EAFCC004E941E /* Taxonomy.m in Sources */ = {isa = PBXBuildFile; fileRef = 4714B7D32C5EAFCC004E941E /* Taxonomy.m */; }; + 479EC6642C5FCBDC00C5630B /* Taxonomy.h in Headers */ = {isa = PBXBuildFile; fileRef = 4714B7D52C5EAFF5004E941E /* Taxonomy.h */; settings = {ATTRIBUTES = (Public, ); }; }; 565E11BB1BD76654005AD47F /* MMDocument.m in Sources */ = {isa = PBXBuildFile; fileRef = 565E11AA1BD76654005AD47F /* MMDocument.m */; }; 565E11BC1BD76654005AD47F /* MMElement.m in Sources */ = {isa = PBXBuildFile; fileRef = 565E11AD1BD76654005AD47F /* MMElement.m */; }; 565E11BD1BD76654005AD47F /* MMGenerator.m in Sources */ = {isa = PBXBuildFile; fileRef = 565E11AF1BD76654005AD47F /* MMGenerator.m */; }; @@ -103,6 +105,7 @@ 565E11C01BD76654005AD47F /* MMParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 565E11B61BD76654005AD47F /* MMParser.m */; }; 565E11C11BD76654005AD47F /* MMScanner.m in Sources */ = {isa = PBXBuildFile; fileRef = 565E11B81BD76654005AD47F /* MMScanner.m */; }; 565E11C21BD76654005AD47F /* MMSpanParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 565E11BA1BD76654005AD47F /* MMSpanParser.m */; }; + 64B3EA282BF7C4AF009E0F38 /* libThirdPartyExtension.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 238E841B1B4FE29A00BFDB32 /* libThirdPartyExtension.a */; }; 64F5220E2BF5C76E00AE6E0F /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 64F5220D2BF5C76E00AE6E0F /* PrivacyInfo.xcprivacy */; }; 64F5220F2BF5C76E00AE6E0F /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 64F5220D2BF5C76E00AE6E0F /* PrivacyInfo.xcprivacy */; }; AC8EFB00BB10FD9E9347B36E /* libPods-ContentstackTest.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1BF5BF157E2FBD4654225A01 /* libPods-ContentstackTest.a */; }; @@ -124,6 +127,20 @@ remoteGlobalIDString = 230B38BF1C16E98B00444A14; remoteInfo = Contentstack; }; + 64B3EA292BF7C4AF009E0F38 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 23A0F84D1B3801D1003334E9 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 238E841A1B4FE29A00BFDB32; + remoteInfo = ThirdPartyExtension; + }; + 64F522152BF7C31900AE6E0F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 23A0F84D1B3801D1003334E9 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 238E841A1B4FE29A00BFDB32; + remoteInfo = ThirdPartyExtension; + }; /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -207,6 +224,8 @@ 23B6F1281B5662EE00A9E983 /* ISO8601DateFormatter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ISO8601DateFormatter.m; sourceTree = ""; }; 23C545FB1C1976FE007BBD27 /* ios-build-framework-script.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = "ios-build-framework-script.sh"; sourceTree = ""; }; 3CF581B9F7526EDA48ED5C6F /* Pods-ContentstackTest.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ContentstackTest.debug.xcconfig"; path = "Target Support Files/Pods-ContentstackTest/Pods-ContentstackTest.debug.xcconfig"; sourceTree = ""; }; + 4714B7D32C5EAFCC004E941E /* Taxonomy.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Taxonomy.m; sourceTree = ""; }; + 4714B7D52C5EAFF5004E941E /* Taxonomy.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Taxonomy.h; sourceTree = ""; }; 565E11A91BD76654005AD47F /* MMDocument.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MMDocument.h; sourceTree = ""; }; 565E11AA1BD76654005AD47F /* MMDocument.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MMDocument.m; sourceTree = ""; }; 565E11AB1BD76654005AD47F /* MMDocument_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MMDocument_Private.h; sourceTree = ""; }; @@ -239,6 +258,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 64B3EA282BF7C4AF009E0F38 /* libThirdPartyExtension.a in Frameworks */, F08A4E439D49C3F08DD8B39C /* libPods-Contentstack.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -315,6 +335,8 @@ 0FD6BAEE29CD6E73001A0930 /* CSURLSessionDelegate.h */, 0F9C0FAF221ADAC90091205A /* ThirdPartyNamespaceHeader */, 230B38C41C16E98B00444A14 /* Info.plist */, + 4714B7D32C5EAFCC004E941E /* Taxonomy.m */, + 4714B7D52C5EAFF5004E941E /* Taxonomy.h */, ); path = Contentstack; sourceTree = ""; @@ -492,6 +514,7 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + 479EC6642C5FCBDC00C5630B /* Taxonomy.h in Headers */, 0F9C0FC8221ADAC90091205A /* NamespacedDependencies.h in Headers */, 23A53F3C1E276C83001DBE35 /* CSIOAPIURLs.h in Headers */, 23A53F3E1E276C83001DBE35 /* CSIOCoreHTTPNetworking.h in Headers */, @@ -539,6 +562,8 @@ ); dependencies = ( 230B39171C1709F800444A14 /* PBXTargetDependency */, + 64F522162BF7C31900AE6E0F /* PBXTargetDependency */, + 64B3EA2A2BF7C4AF009E0F38 /* PBXTargetDependency */, ); name = Contentstack; productName = Contentstack; @@ -769,6 +794,7 @@ 230B38EA1C16EB4400444A14 /* MMScanner.m in Sources */, 230B38E81C16EB4400444A14 /* MMMarkdown.m in Sources */, 230B38E91C16EB4400444A14 /* MMParser.m in Sources */, + 4714B7D42C5EAFCC004E941E /* Taxonomy.m in Sources */, 230B38E51C16EB4400444A14 /* MMElement.m in Sources */, 230B39021C16EB8F00444A14 /* ISO8601DateFormatter.m in Sources */, 230B38E61C16EB4400444A14 /* MMGenerator.m in Sources */, @@ -821,6 +847,16 @@ target = 230B38BF1C16E98B00444A14 /* Contentstack */; targetProxy = 23A53F5B1E277CD3001DBE35 /* PBXContainerItemProxy */; }; + 64B3EA2A2BF7C4AF009E0F38 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 238E841A1B4FE29A00BFDB32 /* ThirdPartyExtension */; + targetProxy = 64B3EA292BF7C4AF009E0F38 /* PBXContainerItemProxy */; + }; + 64F522162BF7C31900AE6E0F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 238E841A1B4FE29A00BFDB32 /* ThirdPartyExtension */; + targetProxy = 64F522152BF7C31900AE6E0F /* PBXContainerItemProxy */; + }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ @@ -839,12 +875,12 @@ ENABLE_TESTABILITY = YES; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", - "$(PROJECT_DIR)/ThirdPartyExtension", + "$(PROJECT_DIR)/ThirdPartyExtension/**", ); GCC_PREFIX_HEADER = ./Contentstack/ThirdPartyNamespaceHeader/NamespacedDependencies.h; INFOPLIST_FILE = Contentstack/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MACH_O_TYPE = staticlib; ONLY_ACTIVE_ARCH = YES; @@ -868,12 +904,12 @@ DYLIB_INSTALL_NAME_BASE = "@rpath"; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", - "$(PROJECT_DIR)/ThirdPartyExtension", + "$(PROJECT_DIR)/ThirdPartyExtension/**", ); GCC_PREFIX_HEADER = ./Contentstack/ThirdPartyNamespaceHeader/NamespacedDependencies.h; INFOPLIST_FILE = Contentstack/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MACH_O_TYPE = staticlib; OTHER_CFLAGS = ""; @@ -917,7 +953,7 @@ 23A0F86A1B3801D1003334E9 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; + ALWAYS_SEARCH_USER_PATHS = YES; BITCODE_GENERATION_MODE = marker; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; @@ -954,7 +990,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = NO; OTHER_CFLAGS = "-fembed-bitcode-marker"; @@ -972,7 +1008,7 @@ 23A0F86B1B3801D1003334E9 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; + ALWAYS_SEARCH_USER_PATHS = YES; BITCODE_GENERATION_MODE = bitcode; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; @@ -1003,7 +1039,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = NO; ONLY_ACTIVE_ARCH = NO; OTHER_CFLAGS = "-fembed-bitcode"; diff --git a/Contentstack.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Contentstack.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/Contentstack.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/Contentstack.xcodeproj/xcshareddata/xcschemes/Contentstack.xcscheme b/Contentstack.xcodeproj/xcshareddata/xcschemes/Contentstack.xcscheme index fb6fe29..1e04b4c 100644 --- a/Contentstack.xcodeproj/xcshareddata/xcschemes/Contentstack.xcscheme +++ b/Contentstack.xcodeproj/xcshareddata/xcschemes/Contentstack.xcscheme @@ -27,6 +27,15 @@ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" shouldUseLaunchSchemeArgsEnv = "YES"> + + + + @@ -39,20 +48,9 @@ - - - - - - - - diff --git a/Contentstack/Contentstack.h b/Contentstack/Contentstack.h index 3762c3b..9e8d7a5 100644 --- a/Contentstack/Contentstack.h +++ b/Contentstack/Contentstack.h @@ -12,6 +12,7 @@ #import #import #import +#import #import #import #import diff --git a/Contentstack/Entry.m b/Contentstack/Entry.m index f4b6f23..885a46d 100644 --- a/Contentstack/Entry.m +++ b/Contentstack/Entry.m @@ -49,6 +49,16 @@ - (instancetype)initWithContentType:(ContentType*)contentType withEntryUID:(NSSt return self; } +- (instancetype)initWithTaxonomy:(Taxonomy *)taxonomy { + if (self = [super init]) { + _taxonomy = taxonomy; + _localHeaders = [NSMutableDictionary dictionary]; + _objectProperties = [NSMutableDictionary dictionary]; + _postParamDictionary = [NSMutableDictionary dictionary]; + } + return self; +} + -(void)setLanguage:(Language)language { _language = language; [self setLocale:[self localeCode:language]]; @@ -63,6 +73,9 @@ - (instancetype)initWithContentType:(ContentType*)contentType { return [self initWithContentType:contentType withEntryUID:nil]; } +//- (instancetype)initWithTaxonomy:(Taxonomy*)taxonomy { +// return [self initWithTaxonomy:taxonomy]; +//} //MARK: - Headers - - (void)setHeader:(NSString *)headerValue forKey:(NSString *)headerKey { diff --git a/Contentstack/Query.h b/Contentstack/Query.h index 3c30e15..e8827e1 100644 --- a/Contentstack/Query.h +++ b/Contentstack/Query.h @@ -130,6 +130,8 @@ This method provides all the entries for the specified language in the response. */ - (void)search:(NSString *)searchString; +- (void)query:(NSDictionary *)queryString; + //MARK: - Tags - /**--------------------------------------------------------------------------------------- * @name Tags @@ -759,6 +761,9 @@ This method provides all the entries from a specified contenttype. */ - (void)find:(void (^) (ResponseType type,QueryResult * BUILT_NULLABLE_P result,NSError * BUILT_NULLABLE_P error))completionBlock; + +- (void)findTaxonomy:(void (^) (ResponseType type,QueryResult * BUILT_NULLABLE_P result,NSError * BUILT_NULLABLE_P error))completionBlock; + /** This method provides the first entry from a specified contenttype. diff --git a/Contentstack/Query.m b/Contentstack/Query.m index db68022..1a74487 100644 --- a/Contentstack/Query.m +++ b/Contentstack/Query.m @@ -12,6 +12,7 @@ #import "CSIOAPIURLs.h" #import "QueryResult.h" #import "ContentType.h" +#import "Taxonomy.h" #import "CSIOInternalHeaders.h" #import "NSObject+Extensions.h" @@ -39,6 +40,16 @@ - (instancetype)initWithContentType:(ContentType*)contentType { return self; } +- (instancetype)initWithTaxonomy:(Taxonomy*)taxonomy { + if (self = [super init]) { + _taxonomy = taxonomy; + _localHeaders = [NSMutableDictionary dictionary]; + _queryDictionary = [NSMutableDictionary dictionary]; + _requestOperationSet = [NSMutableSet set]; + } + return self; +} + //MARK: - Headers - (void)setHeader:(NSString *)headerValue forKey:(NSString *)headerKey { @@ -84,6 +95,11 @@ - (void)tags:(NSArray*)tagsArray { [self.queryDictionary setObject:[tagsArray componentsJoinedByString:@","] forKey:kCSIO_Tags]; } +//MARK: - Query - +- (void)query:(NSDictionary *)query { + [self.queryDictionary setObject:query forKey:kCSIO_Queryable]; +} + ////MARK: - Before/After UID - //- (void)beforeUID:(NSString *)uid { // [self.queryDictionary setObject:uid forKey:kCSIO_BeforeUID]; @@ -501,6 +517,35 @@ - (void)find:(void (^) (ResponseType type,QueryResult * BUILT_NULLABLE_P result, } } +//MARK: Execute Query - + +- (void)findTaxonomy:(void (^) (ResponseType type,QueryResult * BUILT_NULLABLE_P result,NSError * BUILT_NULLABLE_P error))completionBlock { + + [self.queryDictionary setObject:self.taxonomy.stack.environment forKey:kCSIO_Environment]; + + NSMutableDictionary *paramDictionary = [NSMutableDictionary dictionaryWithDictionary:self.queryDictionary]; + + NSMutableDictionary *headers = [NSMutableDictionary dictionaryWithDictionary:self.taxonomy.headers]; + + [headers addEntriesFromDictionary:self.localHeaders]; + + NSString *path = [CSIOAPIURLs fetchTaxonomyWithVersion:self.taxonomy.stack.version]; + + NSURLSessionDataTask *op = [self.taxonomy.stack.network requestForStack:self.taxonomy.stack withURLPath:path requestType:CSIOCoreNetworkingRequestTypeGET params:paramDictionary additionalHeaders:headers cachePolicy:self.cachePolicy completion:^(ResponseType responseType, id responseJSON, NSError *error) { + + if (error) { + completionBlock(responseType, nil, error); + }else { + QueryResult *queryResult = [[QueryResult alloc] initWithTaxonomy:self.taxonomy objectDictionary:responseJSON]; + + completionBlock(responseType, queryResult, nil); + } + }]; + if (op && ![op isKindOfClass:[NSNull class]]) { + [self.requestOperationSet addObject:op]; + } +} + - (void)findOne:(void (^) (ResponseType type,Entry * BUILT_NULLABLE_P entry,NSError * BUILT_NULLABLE_P error))completionBlock { [self.queryDictionary setObject:@(1) forKey:kCSIO_Limit]; diff --git a/Contentstack/QueryResult.h b/Contentstack/QueryResult.h index 568f76e..8f80236 100755 --- a/Contentstack/QueryResult.h +++ b/Contentstack/QueryResult.h @@ -12,12 +12,16 @@ BUILT_ASSUME_NONNULL_BEGIN @class ContentType; +@class Taxonomy; @class Entry; @interface QueryResult : NSObject - (instancetype)init UNAVAILABLE_ATTRIBUTE; +//- (BUILT_NULLABLE NSArray *)getResult; +- (instancetype)initWithTaxonomy:(Taxonomy*)taxonomy objectDictionary:(NSDictionary*)dictionary; + //MARK: Result - /**--------------------------------------------------------------------------------------- * @name Result diff --git a/Contentstack/QueryResult.m b/Contentstack/QueryResult.m index 5d8cd11..968e7b7 100755 --- a/Contentstack/QueryResult.m +++ b/Contentstack/QueryResult.m @@ -10,6 +10,7 @@ #import "CSIOInternalHeaders.h" #import "CSIOConstants.h" #import "ContentType.h" +#import "Taxonomy.h" #import "Entry.h" @interface QueryResult () @@ -30,6 +31,17 @@ - (instancetype)initWithContentType:(ContentType*)contentType objectDictionary:( return self; } +- (instancetype)initWithTaxonomy:(Taxonomy*)taxonomy objectDictionary:(NSDictionary*)dictionary{ + if (self = [super init]) { + self.taxonomy = taxonomy; + self.resultsDictionary = [NSMutableDictionary dictionary]; + if (dictionary) { + [self.resultsDictionary addEntriesFromDictionary:dictionary]; + } + } + return self; +} + - (NSInteger)totalCount { if ([self.resultsDictionary objectForKey:kCSIO_Count]) { @@ -55,7 +67,13 @@ - (NSInteger)totalCount { NSArray *objectsArray = (NSArray*)[self.resultsDictionary objectForKey:kCSIO_Entries]; NSMutableArray *entryObjects = [NSMutableArray array]; // if condition is fix for value of "entries" key ie.array inside array in response JSON - if (objectsArray.firstObject && [objectsArray.firstObject isKindOfClass:[NSArray class]]) { + if (objectsArray.firstObject && [objectsArray.firstObject isKindOfClass:[NSDictionary class]]) { + [objectsArray enumerateObjectsUsingBlock:^(NSDictionary *obj, NSUInteger idx, BOOL * _Nonnull stop) { + Entry *formEntry = [self.taxonomy entry]; + [formEntry configureWithDictionary:obj]; + [entryObjects addObject:formEntry]; + }]; + } else if (objectsArray.firstObject && [objectsArray.firstObject isKindOfClass:[NSArray class]]) { [objectsArray enumerateObjectsUsingBlock:^(NSArray *obj, NSUInteger idx, BOOL * _Nonnull stop) { [obj enumerateObjectsUsingBlock:^(NSDictionary *objDict, NSUInteger idx, BOOL * _Nonnull stop) { Entry *formEntry = [self.contentType entry]; diff --git a/Contentstack/Stack.h b/Contentstack/Stack.h index 18e43c3..b92ffb7 100644 --- a/Contentstack/Stack.h +++ b/Contentstack/Stack.h @@ -11,6 +11,7 @@ @class Config; @class ContentType; +@class Taxonomy; @class AssetLibrary; @class Asset; @class SyncStack; @@ -65,6 +66,8 @@ BUILT_ASSUME_NONNULL_BEGIN */ - (ContentType *)contentTypeWithName:(NSString *)contentTypeName; +- (Taxonomy *)taxonomy; + //MARK: - Manually set headers /**--------------------------------------------------------------------------------------- * @name Manually set headers diff --git a/Contentstack/Stack.m b/Contentstack/Stack.m index 5e2b449..ec23d84 100644 --- a/Contentstack/Stack.m +++ b/Contentstack/Stack.m @@ -11,6 +11,7 @@ #import "CSIOConstants.h" #import "CSIOCoreHTTPNetworking.h" #import "ContentType.h" +#import "Taxonomy.h" #import "CSIOAPIURLs.h" #import "NSObject+Extensions.h" @@ -86,6 +87,12 @@ -(ContentType*)contentTypeWithName:(NSString*)contentTypeName; { return contentType; } +//MARK: - Taxonomy +-(Taxonomy*)taxonomy { + Taxonomy *taxonomy = [[Taxonomy alloc] initWithStack:self]; + return taxonomy; +} + //MARK: - Asset -(Asset *)asset { diff --git a/Contentstack/Taxonomy.h b/Contentstack/Taxonomy.h new file mode 100644 index 0000000..f649978 --- /dev/null +++ b/Contentstack/Taxonomy.h @@ -0,0 +1,108 @@ +// +// Taxonomy.h +// Contentstack +// +// Created by Vikram Kalta on 27/07/2024. +// Copyright © 2024 Contentstack. All rights reserved. +// + +#import +#import "ContentstackDefinitions.h" + +@class Query; + +BUILT_ASSUME_NONNULL_BEGIN + +@interface Taxonomy : NSObject + +- (instancetype)init UNAVAILABLE_ATTRIBUTE; + +//MARK: - Manually set headers +/**--------------------------------------------------------------------------------------- + * @name Manually set headers + * --------------------------------------------------------------------------------------- + */ + +/** +Set a header for ContentType + + //Obj-C + [contentTypeObj setHeader:@"MyValue" forKey:@"My-Custom-Header"]; + //Swift + contentTypeObj.setHeader("MyValue", forKey: "My-Custom-Header") +@param headerValue The header key +@param headerKey The header value +*/ +- (void)setHeader:(NSString *)headerValue forKey:(NSString *)headerKey; +/** +Set a header for ContentType + + //Obj-C + [contentTypeObj addHeadersWithDictionary:@{@"My-Custom-Header": @"MyValue"}]; + + //Swift + contentTypeObj.addHeadersWithDictionary(["My-Custom-Header":"MyValue"]) + + + @param headers The headers as dictionary which needs to be added to the application + */ +- (void)addHeadersWithDictionary:(NSDictionary *)headers; +/** +Removes a header from this ContentType. + + //Obj-C + [contentTypeObj removeHeaderForKey:@"My-Custom-Header"]; + + //Swift + contentTypeObj.removeHeaderForKey("My-Custom-Header") + + @param headerKey The header key that needs to be removed + */ +- (void)removeHeaderForKey:(NSString *)headerKey; +//MARK: - Query +/**--------------------------------------------------------------------------------------- + * @name Query + * --------------------------------------------------------------------------------------- + */ + +/** +Represents a Query on 'ContentType' which can be executed to retrieve entries that pass the query condition + //Obj-C + Query *queryObj = [contentTypeObj query]; + + //Swift + var queryObj:Query = contentTypeObj.query() + + @return Returns new Query instance + */ +- (Query*)query; + +//MARK: - Schema +/**--------------------------------------------------------------------------------------- + * @name ContentType Schema + * --------------------------------------------------------------------------------------- + */ +/** + Gets ContentType Schema defination. + + //Obj-C + + Taxonomy * taxonomy = [stack] + [contentType fetch:params completion:^(NSDictionary * _Nullable entries, NSError * _Nullable error) { + + }]; + + //Swift + + let taxonomy = stack.taxonomy("") + taxonomy.fetch(params, { (entries, error) in + + }) + @param completionBlock block to be called once operation is done. + */ +- (void)fetch:(NSDictionary * _Nullable)params completion:(void (^)(NSDictionary * + BUILT_NULLABLE_P contentType, + NSError * BUILT_NULLABLE_P error))completionBlock; +@end + +BUILT_ASSUME_NONNULL_END diff --git a/Contentstack/Taxonomy.m b/Contentstack/Taxonomy.m new file mode 100644 index 0000000..66b100c --- /dev/null +++ b/Contentstack/Taxonomy.m @@ -0,0 +1,90 @@ +// +// Taxonomy.m +// Contentstack +// +// Created by Vikram Kalta on 27/07/2024. +// Copyright © 2024 Contentstack. All rights reserved. +// + +#import "Taxonomy.h" +#import "CSIOInternalHeaders.h" +#import "CSIOConstants.h" +#import "CSIOCoreHTTPNetworking.h" +#import "CSIOAPIURLs.h" +#import "NSObject+Extensions.h" +#import "Stack.h" +#import "Query.h" + +@interface Taxonomy () +@property (nonatomic, strong, getter=stack) Stack *csStack; +@end + +@implementation Taxonomy + +-(instancetype)initWithStack:(Stack*)stack { + if (self = [super init]) { + _csStack = stack; + _postParamDictionary = [NSMutableDictionary dictionary]; + _headers = [NSMutableDictionary dictionary]; + } + return self; +} + +-(Entry*)entry { + Entry *entry = [[Entry alloc] initWithTaxonomy:self]; + return entry; +} + +-(Query*)query { + Query *query = [[Query alloc] initWithTaxonomy:self]; + return query; +} + +//MARK: - Headers +- (void)setHeader:(NSString *)headerValue forKey:(NSString *)headerKey { + [self.headers setObject:headerValue forKey:headerKey]; +} + +- (void)addHeadersWithDictionary:(NSDictionary *)headers { + [headers enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { + [self.headers setObject:obj forKey:key]; + }]; +} + +- (void)removeHeaderForKey:(NSString *)headerKey { + if (self.headers[headerKey]) { + [self.headers removeObjectForKey:headerKey]; + } +} +//MARK: - Get entries +- (void)fetch:(NSDictionary * _Nullable)params completion:(void (^)(NSDictionary * _Nullable, + NSError * _Nullable))completionBlock { + NSString *path = [CSIOAPIURLs fetchTaxonomyWithVersion:self.stack.version]; + [self.postParamDictionary setObject:_csStack.environment forKey:kCSIO_Environment]; + + NSMutableDictionary *paramDictionary = [NSMutableDictionary dictionaryWithDictionary:self.postParamDictionary]; + for (NSString* key in params) { + [paramDictionary setValue:[params valueForKey:key] forKey:key]; + } + + NSURLSessionDataTask *op = [self.stack.network requestForStack:self.stack withURLPath:path requestType:CSIOCoreNetworkingRequestTypeGET params:paramDictionary additionalHeaders:self.stack.stackHeaders completion:^(ResponseType responseType, id responseJSON, NSError *error) { + if (completionBlock) { + if (error) { + completionBlock(nil, error); + } else { + NSDictionary *responseData = responseJSON; + if ([[responseData allKeys] containsObject:@"entries"] && [responseData objectForKey:@"entries"] != nil && [[responseData objectForKey:@"entries"] isKindOfClass:[NSDictionary class]]) { + completionBlock([responseData objectForKey:@"entries"], nil); + } else { + NSError *error = [NSError errorWithDomain:@"Error" code:-4001 userInfo:@{@"error": @"Failed to retrieve data"}]; + completionBlock(nil, error); + } + } + } + }]; + + if (op && ![op isKindOfClass:[NSNull class]]) { + [self.stack.requestOperationSet addObject:op]; + } +} +@end diff --git a/ContentstackInternal/CSIOAPIURLs.h b/ContentstackInternal/CSIOAPIURLs.h index d2f1eb1..227c0e7 100644 --- a/ContentstackInternal/CSIOAPIURLs.h +++ b/ContentstackInternal/CSIOAPIURLs.h @@ -20,6 +20,9 @@ //Content Type +(NSString *)fetchContenTypeSchema:(NSString*)contentTypeUID withVersion:(NSString*)version; +//Taxonomy ++(NSString *)fetchTaxonomyWithVersion:(NSString*)version; + //Entry + (NSString *)fetchEntryURLWithContentTypeUID:(NSString *)contentTypeUID entryUID:(NSString*)entryUID withVersion:(NSString*)version; diff --git a/ContentstackInternal/CSIOAPIURLs.m b/ContentstackInternal/CSIOAPIURLs.m index d53959d..987fba5 100644 --- a/ContentstackInternal/CSIOAPIURLs.m +++ b/ContentstackInternal/CSIOAPIURLs.m @@ -29,6 +29,8 @@ @implementation CSIOAPIURLs static NSString *fetchContentTypeSchema = @"/%@/content_types/%@"; // sync static NSString *syncData = @"/%@/stacks/sync"; +// Taxonomy +static NSString *fetchTaxonomyWithVersion = @"/%@/taxonomies/entries"; //MARK: Methods - @@ -42,6 +44,11 @@ +(NSString *)fetchContenTypeSchema:(NSString*)contentTypeUID withVersion:(NSStri return [NSString stringWithFormat:fetchContentTypeSchema, version, contentTypeUID]; } +//Taxonomy ++(NSString *)fetchTaxonomyWithVersion:(NSString*)version { + return [NSString stringWithFormat:fetchTaxonomyWithVersion, version]; +} + //Query +(NSString *)fetchContentTypeEntriesQueryURLWithUID:(NSString *)contentTypeUID withVersion:(NSString*)version{ return [NSString stringWithFormat:fetchContentTypeEntriesQuery,version,contentTypeUID]; diff --git a/ContentstackInternal/CSIOInternalHeaders.h b/ContentstackInternal/CSIOInternalHeaders.h index ca1c39f..458a057 100644 --- a/ContentstackInternal/CSIOInternalHeaders.h +++ b/ContentstackInternal/CSIOInternalHeaders.h @@ -12,6 +12,7 @@ #import #import "Query.h" #import "ContentType.h" +#import "Taxonomy.h" #import "Entry.h" #import "Asset.h" #import "QueryResult.h" @@ -45,14 +46,16 @@ @interface Query () @property (nonatomic, assign) BOOL shouldFetchFromNetwork; @property (nonatomic, strong) ContentType *contentType; +@property (nonatomic, strong) Taxonomy *taxonomy; - (instancetype)initWithContentType:(ContentType *)contentType; @property (nonatomic, strong) NSMutableDictionary *queryDictionary; - +- (instancetype)initWithTaxonomy:(Taxonomy *)taxonomy; @end @interface QueryResult () - (instancetype)initWithContentType:(ContentType *)contentType objectDictionary:(NSDictionary*)dictionary; @property (nonatomic, strong) ContentType *contentType; +@property (nonatomic, strong) Taxonomy *taxonomy; @end @interface ContentType () @@ -68,11 +71,23 @@ @interface Entry () @property (nonatomic, assign, getter=isDeleted) BOOL deleted; @property (nonatomic, strong) ContentType *contentType; +@property (nonatomic, strong) Taxonomy *taxonomy; @property (nonatomic, strong) NSMutableDictionary *postParamDictionary; - (instancetype)initWithContentType:(ContentType *)contentType; - (instancetype)initWithContentType:(ContentType *)contentType withEntryUID:(NSString*)uid; +- (instancetype)initWithTaxonomy:(Taxonomy *)taxonomy; @end + +@interface Taxonomy () +@property (nonatomic, strong) NSMutableDictionary *headers; +@property (nonatomic, strong) NSMutableDictionary *postParamDictionary; + +-(instancetype)initWithStack:(Stack *)stack; +-(Stack *)stack; +-(Entry *)entry; +@end + @interface Asset () - (instancetype)initWithStack:(Stack *)stack; - (instancetype)initWithStack:(Stack *)stack withAssetUID:(NSString*)assetUID; diff --git a/ContentstackTest/ContentstackTest.m b/ContentstackTest/ContentstackTest.m index 6e3cfe1..ef4c109 100644 --- a/ContentstackTest/ContentstackTest.m +++ b/ContentstackTest/ContentstackTest.m @@ -51,10 +51,10 @@ - (void)URLSession:(NSURLSession * _Nonnull)session task:(NSURLSessionTask * _No @end static NSInteger kRequestTimeOutInSeconds = 400; -static NSString *_productUid = @""; +static NSString *_sourceUid = @""; static NSString *_assetUid = @""; -static NSString *_multiplefieldtUid = @""; -static NSString *_userUid = @""; +static NSString *_modularblockUid = @""; +static NSString *_numbersContentTypeUid = @""; @interface Query(HeaderTest) @@ -119,10 +119,10 @@ - (void)tearDown { #pragma mark Test Case - Header -- (void)test01FetchProductEntries { +- (void)test01FetchSourceEntries { XCTestExpectation *expectation = [self expectationWithDescription:@"Fetch All Entries"]; - ContentType* csForm = [csStack contentTypeWithName:@"product"]; + ContentType* csForm = [csStack contentTypeWithName:@"source"]; Query* csQuery = [csForm query]; [csQuery find:^(ResponseType type, QueryResult *result, NSError *error) { XCTAssert(type == NETWORK, @"Pass"); @@ -131,7 +131,7 @@ - (void)test01FetchProductEntries { }else { [self testProductCount:[result getResult]]; Entry *obj = [result getResult][0]; - _productUid = obj.uid; + _sourceUid = obj.uid; } [expectation fulfill]; }]; @@ -140,10 +140,10 @@ - (void)test01FetchProductEntries { } -- (void)test02FetchMultifieldEntries { +- (void)test02FetchModularBlockEntries { XCTestExpectation *expectation = [self expectationWithDescription:@"Fetch All Entries"]; - ContentType* csForm = [csStack contentTypeWithName:@"multifield"]; + ContentType* csForm = [csStack contentTypeWithName:@"modular_block"]; Query* csQuery = [csForm query]; [csQuery find:^(ResponseType type, QueryResult *result, NSError *error) { XCTAssert(type == NETWORK, @"Pass"); @@ -152,7 +152,7 @@ - (void)test02FetchMultifieldEntries { }else { [self testProductCount:[result getResult]]; Entry *obj = [result getResult][0]; - _multiplefieldtUid = obj.uid; + _modularblockUid = obj.uid; } [expectation fulfill]; }]; @@ -161,10 +161,10 @@ - (void)test02FetchMultifieldEntries { } -- (void)test03FetchUserEntries { +- (void)test03FetchNumbersContentTypeEntries { XCTestExpectation *expectation = [self expectationWithDescription:@"Fetch All Entries"]; - ContentType* csForm = [csStack contentTypeWithName:@"user"]; + ContentType* csForm = [csStack contentTypeWithName:@"numbers_content_type"]; Query* csQuery = [csForm query]; [csQuery find:^(ResponseType type, QueryResult *result, NSError *error) { XCTAssert(type == NETWORK, @"Pass"); @@ -173,7 +173,7 @@ - (void)test03FetchUserEntries { }else { [self testProductCount:[result getResult]]; Entry *obj = [result getResult][0]; - _userUid = obj.uid; + _numbersContentTypeUid = obj.uid; } [expectation fulfill]; }]; @@ -207,7 +207,7 @@ - (void)test04FetchAssets { - (void)testGetHeader { XCTestExpectation *expectation = [self expectationWithDescription:@"Fetch Set Header"]; - ContentType* csForm = [csStack contentTypeWithName:@"product"]; + ContentType* csForm = [csStack contentTypeWithName:@"source"]; Query* csQuery = [csForm query]; [csQuery whereKey:@"in_stock" equalTo:@(YES)]; [csQuery findOne:^(ResponseType type, Entry * _Nullable entry, NSError * _Nullable error) { @@ -231,9 +231,9 @@ -(void)testValueForKey { XCTestExpectation *expectation = [self expectationWithDescription:@"Value For Key"]; - ContentType* csForm = [csStack contentTypeWithName:@"product"]; + ContentType* csForm = [csStack contentTypeWithName:@"source"]; - Entry *entry = [csForm entryWithUID:_productUid]; + Entry *entry = [csForm entryWithUID:_sourceUid]; [entry fetch:^(ResponseType type, NSError *error) { if (error) { @@ -255,12 +255,12 @@ -(void)testValueForKey { } -(void)testKVOEntryProperties { - + // not sure what KVO means, just updating the test to pass for now XCTestExpectation *expectation = [self expectationWithDescription:@"KVO on Properties"]; - ContentType* csForm = [csStack contentTypeWithName:@"multifield"]; - _kvoEntry = [csForm entryWithUID:_multiplefieldtUid]; - [_kvoEntry.properties addObserver:self forKeyPath:@"description" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil]; + ContentType* csForm = [csStack contentTypeWithName:@"modular_block"]; + _kvoEntry = [csForm entryWithUID:_modularblockUid]; + [_kvoEntry.properties addObserver:self forKeyPath:@"single_path" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil]; [_kvoEntry fetch:^(ResponseType type, NSError *error) { if (error) { @@ -278,9 +278,9 @@ -(void)testKVOEntryProperties { -(void)testKVOEntryForGroup { XCTestExpectation *expectation = [self expectationWithDescription:@"KVO on Properties"]; - ContentType* csForm = [csStack contentTypeWithName:@"multifield"]; - _kvoEntry = [csForm entryWithUID:_multiplefieldtUid]; - [_kvoEntry.properties addObserver:self forKeyPath:@"singlegroup.singlesubgruop.ssg_boolean" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil]; + ContentType* csForm = [csStack contentTypeWithName:@"modular_block"]; + _kvoEntry = [csForm entryWithUID:_modularblockUid]; + [_kvoEntry.properties addObserver:self forKeyPath:@"modular_blocks.boolean" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil]; [_kvoEntry fetch:^(ResponseType type, NSError *error) { if (error) { @@ -331,7 +331,7 @@ -(void)testProductCount:(NSArray *)resultArray { -(void)testFetchContentType { XCTestExpectation *expectation = [self expectationWithDescription:@"GET"]; - ContentType *contentType = [csStack contentTypeWithName:@"product"]; + ContentType *contentType = [csStack contentTypeWithName:@"source"]; [contentType fetch:nil completion:^(NSDictionary * _Nullable contentType, NSError * _Nullable error) { XCTAssertTrue([contentType isKindOfClass:[NSDictionary class]], @"array value should be NSDictionary"); XCTAssertTrue([contentType[@"schema"] isKindOfClass:[NSArray class]], @"Value of key should be NSArray"); @@ -349,7 +349,7 @@ -(void)testFetchContentType { -(void)testFetchContentTypeIncludingGlobalFields { XCTestExpectation *expectation = [self expectationWithDescription:@"GET"]; - ContentType *contentType = [csStack contentTypeWithName:@"product"]; + ContentType *contentType = [csStack contentTypeWithName:@"source"]; [contentType fetch:@{@"include_global_field_schema": @"true"} completion:^(NSDictionary * _Nullable contentType, NSError * _Nullable error) { XCTAssertTrue([contentType isKindOfClass:[NSDictionary class]], @"array value should be NSDictionary"); XCTAssertTrue([contentType[@"schema"] isKindOfClass:[NSArray class]], @"Value of key should be NSArray"); @@ -411,9 +411,9 @@ - (void)testFetchMarkDownString { XCTestExpectation *expectation = [self expectationWithDescription:@"Fetch mark down string"]; - ContentType* csForm = [csStack contentTypeWithName:@"user"]; + ContentType* csForm = [csStack contentTypeWithName:@"numbers_content_type"]; - Entry *entry = [csForm entryWithUID:_userUid]; + Entry *entry = [csForm entryWithUID:_numbersContentTypeUid]; [entry fetch:^(ResponseType type, NSError *error) { if (error) { @@ -447,8 +447,8 @@ - (void)testFetchMarkDownArray { XCTestExpectation *expectation = [self expectationWithDescription:@"Fetch Mark Down Array"]; - ContentType* csForm = [csStack contentTypeWithName:@"user"]; - Entry *entry = [csForm entryWithUID:_userUid]; + ContentType* csForm = [csStack contentTypeWithName:@"numbers_content_type"]; + Entry *entry = [csForm entryWithUID:_numbersContentTypeUid]; [entry fetch:^(ResponseType type, NSError *error) { if (error) { @@ -572,10 +572,10 @@ - (void)testGroup { XCTestExpectation *expectation = [self expectationWithDescription:@"Fetch group"]; - ContentType* csForm = [csStack contentTypeWithName:@"multifield"]; - Entry *entry = [csForm entryWithUID:_multiplefieldtUid]; + ContentType* csForm = [csStack contentTypeWithName:@"modular_block"]; + Entry *entry = [csForm entryWithUID:_modularblockUid]; - [entry includeRefFieldWithKey:@[@"singlegroup.singleref"]]; +// [entry includeRefFieldWithKey:@[@"singlegroup.singleref"]]; [entry fetch:^(ResponseType type, NSError * _Nonnull error) { if (error) { XCTFail(@"~ ERR: %@, Message = %@", error.userInfo, error.description); @@ -584,10 +584,10 @@ - (void)testGroup { Group *grp = [entry groupForKey:@"singlegroup"]; XCTAssertNotNil([grp objectForKey:@"title"],@"Group object not configured"); - Group *subgrp = [grp groupForKey:@"singlesubgruop"]; + Group *subgrp = [grp groupForKey:@"singlesubgroup"]; XCTAssertNotNil([subgrp objectForKey:@"ssg_date"],@"Group object not configured"); - NSArray *refEntries = [grp entriesForKey:@"singleref" withContentType:@"product"]; + NSArray *refEntries = [grp entriesForKey:@"singleref" withContentType:@"source"]; XCTAssert(refEntries.count > 0 ,@"entries object not configured"); NSArray *assetArray = [entry assetsForKey:@"file"]; @@ -627,9 +627,9 @@ - (void)testFetch { XCTestExpectation *expectation = [self expectationWithDescription:@"Fetch Entry"]; - ContentType* csForm = [csStack contentTypeWithName:@"product"]; + ContentType* csForm = [csStack contentTypeWithName:@"source"]; - __block NSString *uid = _productUid; + __block NSString *uid = _sourceUid; Entry *entry = [csForm entryWithUID:uid]; [entry fetch:^(ResponseType type, NSError * _Nonnull error) { @@ -654,22 +654,22 @@ - (void)testFetchIncludeRefContentTypeUid { XCTestExpectation *expectation = [self expectationWithDescription:@"Fetch Single Entry with Reference Content type"]; - ContentType* csForm = [csStack contentTypeWithName:@"product"]; + ContentType* csForm = [csStack contentTypeWithName:@"source"]; - Entry *entry = [csForm entryWithUID:_productUid]; + Entry *entry = [csForm entryWithUID:_sourceUid]; [entry includeReferenceContentTypeUid]; [entry fetch:^(ResponseType type, NSError *error) { if (error) { XCTFail(@"~ ERR: %@, Message = %@", error.userInfo, error.description); }else { - if ([[entry valueForKey:@"category"] isKindOfClass:[NSArray class]]) { - NSArray *catArray = [entry valueForKey:@"category"]; - for (id category in catArray) { - XCTAssertTrue([category isKindOfClass:[NSDictionary class]], "Category should be of type NSDictionary."); - if ([category isKindOfClass:[NSDictionary class]]) { - NSDictionary *catagoryDict = category; - XCTAssertTrue([catagoryDict.allKeys containsObject:@"_content_type_uid"], "Category should have '_content_type_uid' key."); + if ([[entry valueForKey:@"reference"] isKindOfClass:[NSArray class]]) { + NSArray *refArray = [entry valueForKey:@"reference"]; + for (id reference in refArray) { + XCTAssertTrue([reference isKindOfClass:[NSDictionary class]], "Reference should be of type NSDictionary."); + if ([reference isKindOfClass:[NSDictionary class]]) { + NSDictionary *referenceDict = reference; + XCTAssertTrue([referenceDict.allKeys containsObject:@"_content_type_uid"], "Category should have '_content_type_uid' key."); } } } @@ -685,13 +685,13 @@ - (void)testFetchIncludeOnlyFields { XCTestExpectation *expectation = [self expectationWithDescription:@"Fetch Single Entry"]; - ContentType* csForm = [csStack contentTypeWithName:@"product"]; + ContentType* csForm = [csStack contentTypeWithName:@"source"]; - Entry *entry = [csForm entryWithUID:_productUid]; + Entry *entry = [csForm entryWithUID:_sourceUid]; __block NSMutableArray *includeFields = [NSMutableArray array]; [includeFields addObject:@"price"]; - [includeFields addObject:@"title"]; + [includeFields addObject:@"number"]; [entry includeOnlyFields:includeFields]; @@ -722,12 +722,12 @@ - (void)testFetchIncludeAllFieldsExcept { XCTestExpectation *expectation = [self expectationWithDescription:@"Entry Include All Fields Except Fields"]; - ContentType* csForm = [csStack contentTypeWithName:@"product"]; + ContentType* csForm = [csStack contentTypeWithName:@"source"]; - Entry *entry = [csForm entryWithUID:_productUid]; + Entry *entry = [csForm entryWithUID:_sourceUid]; __block NSMutableArray *includeAllFieldsExceptFields = [NSMutableArray array]; - [includeAllFieldsExceptFields addObject:@"price"]; + [includeAllFieldsExceptFields addObject:@"number"]; [entry includeAllFieldsExcept:includeAllFieldsExceptFields]; @@ -758,14 +758,14 @@ - (void)testFetchIncludeRefFieldWithKeyOnlyRefValue { XCTestExpectation *expectation = [self expectationWithDescription:@"Fetch Single Entry"]; - ContentType* csForm = [csStack contentTypeWithName:@"product"]; + ContentType* csForm = [csStack contentTypeWithName:@"source"]; - Entry *entry = [csForm entryWithUID:_productUid]; + Entry *entry = [csForm entryWithUID:_sourceUid]; __block NSMutableArray *includeFields = [NSMutableArray array]; [includeFields addObject:@"title"]; - [entry includeRefFieldWithKey:@"category" andOnlyRefValuesWithKeys:includeFields]; + [entry includeRefFieldWithKey:@"reference" andOnlyRefValuesWithKeys:includeFields]; [entry fetch:^(ResponseType type, NSError *error) { @@ -775,13 +775,13 @@ - (void)testFetchIncludeRefFieldWithKeyOnlyRefValue { [self checkLanguageStatus:entry]; - if ([entry objectForKey:@"category"]) { + if ([entry objectForKey:@"reference"]) { [includeFields addObject:@"uid"]; [includeFields addObject:@"_metadata"]; [includeFields addObject:@"_content_type_uid"]; - [[entry objectForKey:@"category"] enumerateObjectsUsingBlock:^(NSDictionary *obj, NSUInteger idx, BOOL * _Nonnull stop) { + [[entry objectForKey:@"reference"] enumerateObjectsUsingBlock:^(NSDictionary *obj, NSUInteger idx, BOOL * _Nonnull stop) { [[obj allKeys] enumerateObjectsUsingBlock:^(NSString *key, NSUInteger idx, BOOL * _Nonnull stop) { if (![includeFields containsObject:key]) { @@ -808,14 +808,14 @@ - (void)testFetchIncludeRefFieldWithKeyExcludeRefValue { XCTestExpectation *expectation = [self expectationWithDescription:@"Fetch Single Entry"]; - ContentType* csForm = [csStack contentTypeWithName:@"product"]; + ContentType* csForm = [csStack contentTypeWithName:@"source"]; - Entry *entry = [csForm entryWithUID:_productUid]; + Entry *entry = [csForm entryWithUID:_sourceUid]; __block NSMutableArray *includeAllFieldsExceptFields = [NSMutableArray array]; [includeAllFieldsExceptFields addObject:@"title"]; - [entry includeRefFieldWithKey:@"category" excludingRefValuesWithKeys:includeAllFieldsExceptFields]; + [entry includeRefFieldWithKey:@"reference" excludingRefValuesWithKeys:includeAllFieldsExceptFields]; [entry fetch:^(ResponseType type, NSError *error) { @@ -825,9 +825,9 @@ - (void)testFetchIncludeRefFieldWithKeyExcludeRefValue { [self checkLanguageStatus:entry]; - if ([entry objectForKey:@"category"]) { + if ([entry objectForKey:@"reference"]) { - [[entry objectForKey:@"category"] enumerateObjectsUsingBlock:^(NSDictionary *obj, NSUInteger idx, BOOL * _Nonnull stop) { + [[entry objectForKey:@"reference"] enumerateObjectsUsingBlock:^(NSDictionary *obj, NSUInteger idx, BOOL * _Nonnull stop) { [includeAllFieldsExceptFields enumerateObjectsUsingBlock:^(NSString *key, NSUInteger idx, BOOL * _Nonnull stop) { if ([[obj allKeys] containsObject:key]) { @@ -886,7 +886,7 @@ -(void)checkSpanishLanguageStatus:(Entry *)obj { - (void)testFetchAllEntries { XCTestExpectation *expectation = [self expectationWithDescription:@"Fetch All Entries"]; - ContentType* csForm = [csStack contentTypeWithName:@"product"]; + ContentType* csForm = [csStack contentTypeWithName:@"source"]; Query* csQuery = [csForm query]; [csQuery find:^(ResponseType type, QueryResult *result, NSError *error) { XCTAssert(type == NETWORK, @"Pass"); @@ -897,7 +897,7 @@ - (void)testFetchAllEntries { [[result getResult] enumerateObjectsUsingBlock:^(Entry *obj, NSUInteger idx, BOOL * _Nonnull stop) { [self checkLanguageStatus:obj]; }]; - XCTAssertTrue([result getResult].count > 0, @"Product count should not be 0"); + XCTAssertTrue([result getResult].count > 0, @"Source entry count should not be 0"); } [expectation fulfill]; }]; @@ -928,9 +928,9 @@ - (void)testFetchNonExistingContentType { - (void)testFetchEntryEqualToField { XCTestExpectation *expectation = [self expectationWithDescription:@"Fetch Equal to Entries"]; - ContentType* csForm = [csStack contentTypeWithName:@"categories"]; + ContentType* csForm = [csStack contentTypeWithName:@"source"]; Query* csQuery = [csForm query]; - __block NSString *objectValue = @"Women"; + __block NSString *objectValue = @"source"; [csQuery whereKey:@"title" equalTo:objectValue]; [csQuery find:^(ResponseType type, QueryResult *result, NSError *error) { @@ -963,9 +963,9 @@ - (void)testFetchEntryNotEqualToField { XCTestExpectation *expectation = [self expectationWithDescription:@"Fetch Not Equal To Entries"]; - ContentType* csForm = [csStack contentTypeWithName:@"categories"]; + ContentType* csForm = [csStack contentTypeWithName:@"source"]; Query* csQuery = [csForm query]; - [csQuery whereKey:@"title" notEqualTo:@"Women"]; + [csQuery whereKey:@"title" notEqualTo:@"source"]; [csQuery find:^(ResponseType type, QueryResult *result, NSError *error) { @@ -980,7 +980,7 @@ - (void)testFetchEntryNotEqualToField { [self checkLanguageStatus:obj]; - XCTAssertFalse([[obj objectForKey:@"title"] isEqualToString:@"Women"], @"Value exist for specified key"); + XCTAssertFalse([[obj objectForKey:@"title"] isEqualToString:@"source"], @"Value exist for specified key"); } }]; } @@ -994,9 +994,9 @@ - (void)testFetchEntriesGreaterThanOrEqualTo { XCTestExpectation *expectation = [self expectationWithDescription:@"Fetch Greater than or Equal To Entries"]; - ContentType* csForm = [csStack contentTypeWithName:@"product"]; + ContentType* csForm = [csStack contentTypeWithName:@"source"]; Query* csQuery = [csForm query]; - [csQuery whereKey:@"price" greaterThanOrEqualTo:@(99)]; + [csQuery whereKey:@"number" greaterThanOrEqualTo:@(99)]; [csQuery find:^(ResponseType type, QueryResult *result, NSError *error) { @@ -1011,7 +1011,7 @@ - (void)testFetchEntriesGreaterThanOrEqualTo { [self checkLanguageStatus:obj]; - XCTAssertTrue([[obj objectForKey:@"price"] integerValue] >= 99, @"Value exist for price less than the given price"); + XCTAssertTrue([[obj objectForKey:@"number"] integerValue] >= 99, @"Value exist for price less than the given price"); } }]; } @@ -1025,9 +1025,9 @@ - (void)testFetchEntriesLessThanOrEqualTo { XCTestExpectation *expectation = [self expectationWithDescription:@"Fetch Less than or Equal To Entries"]; - ContentType* csForm = [csStack contentTypeWithName:@"product"]; + ContentType* csForm = [csStack contentTypeWithName:@"source"]; Query* csQuery = [csForm query]; - [csQuery whereKey:@"price" lessThanOrEqualTo:@(99)]; + [csQuery whereKey:@"number" lessThanOrEqualTo:@(99)]; [csQuery find:^(ResponseType type, QueryResult *result, NSError *error) { @@ -1042,7 +1042,7 @@ - (void)testFetchEntriesLessThanOrEqualTo { [self checkLanguageStatus:obj]; - XCTAssertTrue([[obj objectForKey:@"price"] integerValue] <= 99, @"Value exist for price greater than the given price"); + XCTAssertTrue([[obj objectForKey:@"number"] integerValue] <= 99, @"Value exist for price greater than the given price"); } }]; } @@ -1056,9 +1056,9 @@ - (void)testFetchEntriesGreaterThan { XCTestExpectation *expectation = [self expectationWithDescription:@"Fetch Greater than Entries"]; - ContentType* csForm = [csStack contentTypeWithName:@"product"]; + ContentType* csForm = [csStack contentTypeWithName:@"source"]; Query* csQuery = [csForm query]; - [csQuery whereKey:@"price" greaterThan:@(99)]; + [csQuery whereKey:@"number" greaterThan:@(99)]; [csQuery find:^(ResponseType type, QueryResult *result, NSError *error) { @@ -1073,7 +1073,7 @@ - (void)testFetchEntriesGreaterThan { [self checkLanguageStatus:obj]; - XCTAssertTrue([[obj objectForKey:@"price"] integerValue] > 99, @"Value exist for price less than or equal to the given price"); + XCTAssertTrue([[obj objectForKey:@"number"] integerValue] > 99, @"Value exist for price less than or equal to the given price"); } }]; } @@ -1087,9 +1087,9 @@ - (void)testFetchEntriesLessThan { XCTestExpectation *expectation = [self expectationWithDescription:@"Fetch Greater than Entries"]; - ContentType* csForm = [csStack contentTypeWithName:@"product"]; + ContentType* csForm = [csStack contentTypeWithName:@"source"]; Query* csQuery = [csForm query]; - [csQuery whereKey:@"price" lessThan:@(99)]; + [csQuery whereKey:@"number" lessThan:@(99)]; [csQuery find:^(ResponseType type, QueryResult *result, NSError *error) { @@ -1104,7 +1104,7 @@ - (void)testFetchEntriesLessThan { [self checkLanguageStatus:obj]; - XCTAssertTrue([[obj objectForKey:@"price"] integerValue] < 99, @"Value exist for price greater than or equal to the given price"); + XCTAssertTrue([[obj objectForKey:@"number"] integerValue] < 99, @"Value exist for price greater than or equal to the given price"); } }]; } @@ -1118,10 +1118,10 @@ - (void)testFetchEntriesLessThan { - (void)testFetchWhereKeyContainedIn { XCTestExpectation *expectation = [self expectationWithDescription:@"contained In"]; - ContentType* csForm = [csStack contentTypeWithName:@"product"]; + ContentType* csForm = [csStack contentTypeWithName:@"source"]; Query* csQuery = [csForm query]; - __block NSMutableArray *keys = [NSMutableArray arrayWithArray:@[@"Roti Maker", @"kids dress"]]; + __block NSMutableArray *keys = [NSMutableArray arrayWithArray:@[@"source", @"regex validation"]]; [csQuery whereKey:@"title" containedIn:keys]; @@ -1153,9 +1153,9 @@ - (void)testFetchWhereKeyNotContainedIn { XCTestExpectation *expectation = [self expectationWithDescription:@"Fetch Entries"]; - ContentType* csForm = [csStack contentTypeWithName:@"product"]; + ContentType* csForm = [csStack contentTypeWithName:@"source"]; Query* csQuery = [csForm query]; - __block NSMutableArray *keys = [NSMutableArray arrayWithArray:@[@"Roti Maker", @"kids dress"]]; + __block NSMutableArray *keys = [NSMutableArray arrayWithArray:@[@"regex validation"]]; [csQuery whereKey:@"title" notContainedIn:keys]; [csQuery find:^(ResponseType type, QueryResult *result, NSError *error) { @@ -1185,13 +1185,13 @@ - (void)testFetchorWithSubqueries { XCTestExpectation *expectation = [self expectationWithDescription:@"Fetch entries combining subqueries with OR"]; - ContentType* csForm = [csStack contentTypeWithName:@"product"]; + ContentType* csForm = [csStack contentTypeWithName:@"source"]; Query *query1 = [csForm query]; - [query1 whereKey:@"price" greaterThanOrEqualTo:@(99)]; + [query1 whereKey:@"number" greaterThanOrEqualTo:@(99)]; Query *query2 = [csForm query]; - [query2 whereKey:@"in_stock" equalTo:@(YES)]; + [query2 whereKey:@"boolean" equalTo:@(YES)]; Query* csQuery = [csForm query]; [csQuery orWithSubqueries:@[query1, query2]]; @@ -1207,7 +1207,7 @@ - (void)testFetchorWithSubqueries { [self checkLanguageStatus:entry]; - XCTAssertTrue((([[entry objectForKey:@"price"] intValue] >= 99) || [[entry objectForKey:@"in_stock"] boolValue]), @"condition not specified for query"); + XCTAssertTrue((([[entry objectForKey:@"number"] intValue] >= 99) || [[entry objectForKey:@"boolean"] boolValue]), @"condition not specified for query"); } } @@ -1222,13 +1222,13 @@ - (void)testFetchAndWithSubqueries { XCTestExpectation *expectation = [self expectationWithDescription:@"Fetch entries combining subqueries with AND"]; - ContentType* csForm = [csStack contentTypeWithName:@"product"]; + ContentType* csForm = [csStack contentTypeWithName:@"source"]; Query *query1 = [csForm query]; - [query1 whereKey:@"price" greaterThanOrEqualTo:@(99)]; + [query1 whereKey:@"number" greaterThanOrEqualTo:@(99)]; Query *query2 = [csForm query]; - [query2 whereKey:@"in_stock" equalTo:@(YES)]; + [query2 whereKey:@"boolean" equalTo:@(YES)]; Query* csQuery = [csForm query]; [csQuery andWithSubqueries:@[query1, query2]]; @@ -1243,7 +1243,7 @@ - (void)testFetchAndWithSubqueries { for (Entry *entry in [result getResult]) { [self checkLanguageStatus:entry]; - XCTAssertTrue((([[entry objectForKey:@"price"] intValue] >= 99) && [[entry objectForKey:@"in_stock"] boolValue]), @"condition not specified for query"); + XCTAssertTrue((([[entry objectForKey:@"number"] intValue] >= 99) && [[entry objectForKey:@"boolean"] boolValue]), @"condition not specified for query"); } } @@ -1258,7 +1258,7 @@ - (void)testFetchOrderByAscending { XCTestExpectation *expectation = [self expectationWithDescription:@"Fetch Entries in Ascending Order"]; - ContentType* csForm = [csStack contentTypeWithName:@"product"]; + ContentType* csForm = [csStack contentTypeWithName:@"source"]; Query* csQuery = [csForm query]; [csQuery orderByAscending:@"created_at"]; @@ -1298,7 +1298,7 @@ - (void)testFetchOrderByDescending { XCTestExpectation *expectation = [self expectationWithDescription:@"Fetch Entries in Descending Order"]; - ContentType* csForm = [csStack contentTypeWithName:@"product"]; + ContentType* csForm = [csStack contentTypeWithName:@"source"]; Query* csQuery = [csForm query]; [csQuery orderByDescending:@"created_at"]; @@ -1338,7 +1338,7 @@ - (void)testFetchWhereKeyExists { XCTestExpectation *expectation = [self expectationWithDescription:@"Fetch Key for entry"]; - ContentType* csForm = [csStack contentTypeWithName:@"product"]; + ContentType* csForm = [csStack contentTypeWithName:@"source"]; Query* csQuery = [csForm query]; [csQuery whereKeyExists:@"title"]; @@ -1369,7 +1369,7 @@ - (void)testFetchWhereKeyDoesNotExists { XCTestExpectation *expectation = [self expectationWithDescription:@"Fetch key which does not exist in entry"]; - ContentType* csForm = [csStack contentTypeWithName:@"product"]; + ContentType* csForm = [csStack contentTypeWithName:@"source"]; Query* csQuery = [csForm query]; [csQuery whereKeyDoesNotExist:@"image"]; @@ -1396,10 +1396,10 @@ - (void)testFetchOnlyFields { XCTestExpectation *expectation = [self expectationWithDescription:@"Fetch Entries"]; - ContentType* csForm = [csStack contentTypeWithName:@"product"]; + ContentType* csForm = [csStack contentTypeWithName:@"source"]; Query* csQuery = [csForm query]; - __block NSMutableArray *fetchOnlyFields = [NSMutableArray arrayWithArray:@[@"price", @"title"]]; + __block NSMutableArray *fetchOnlyFields = [NSMutableArray arrayWithArray:@[@"number", @"title"]]; [csQuery onlyFields:fetchOnlyFields]; [csQuery find:^(ResponseType type, QueryResult *result, NSError *error) { @@ -1433,10 +1433,10 @@ - (void)testFetchExceptFields { XCTestExpectation *expectation = [self expectationWithDescription:@"Fetch Entries"]; - ContentType* csForm = [csStack contentTypeWithName:@"product"]; + ContentType* csForm = [csStack contentTypeWithName:@"source"]; Query* csQuery = [csForm query]; - __block NSMutableArray *fetchExceptFields = [NSMutableArray arrayWithArray:@[@"price", @"title"]]; + __block NSMutableArray *fetchExceptFields = [NSMutableArray arrayWithArray:@[@"number", @"title"]]; [csQuery exceptFields:fetchExceptFields]; [csQuery find:^(ResponseType type, QueryResult *result, NSError *error) { @@ -1472,11 +1472,11 @@ - (void)testFetchIncludeReferenceFieldWithKey { XCTestExpectation *expectation = [self expectationWithDescription:@"Fetch Entries"]; - ContentType* csForm = [csStack contentTypeWithName:@"product"]; + ContentType* csForm = [csStack contentTypeWithName:@"source"]; Query* csQuery = [csForm query]; - [csQuery includeReferenceFieldWithKey:@[@"category"]]; + [csQuery includeReferenceFieldWithKey:@[@"reference"]]; [csQuery find:^(ResponseType type, QueryResult *result, NSError *error) { @@ -1488,7 +1488,7 @@ - (void)testFetchIncludeReferenceFieldWithKey { [[result getResult] enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { if ([obj isKindOfClass:[Entry class]]) { [self checkLanguageStatus:obj]; - [[obj objectForKey:@"category"] enumerateObjectsUsingBlock:^(id _Nonnull catObj, NSUInteger idx, BOOL * _Nonnull stop) { + [[obj objectForKey:@"reference"] enumerateObjectsUsingBlock:^(id _Nonnull catObj, NSUInteger idx, BOOL * _Nonnull stop) { if ([catObj isKindOfClass:[Entry class]]) { XCTAssertTrue(([[catObj allKeys] containsObject:@"title"]), @"Undefined Key"); @@ -1509,11 +1509,11 @@ - (void)testFetchIncludeReferenceFieldWithKeyOnlyFields { XCTestExpectation *expectation = [self expectationWithDescription:@"Fetch Entries"]; - ContentType* csForm = [csStack contentTypeWithName:@"product"]; + ContentType* csForm = [csStack contentTypeWithName:@"source"]; Query* csQuery = [csForm query]; __block NSMutableArray *fetchOnlyFieldsOfReferenceField = [NSMutableArray arrayWithArray:@[@"title"]]; - [csQuery includeReferenceFieldWithKey:@"category" onlyFields:fetchOnlyFieldsOfReferenceField]; + [csQuery includeReferenceFieldWithKey:@"reference" onlyFields:fetchOnlyFieldsOfReferenceField]; [csQuery find:^(ResponseType type, QueryResult *result, NSError *error) { @@ -1527,13 +1527,13 @@ - (void)testFetchIncludeReferenceFieldWithKeyOnlyFields { [self checkLanguageStatus:entry]; - if ([entry objectForKey:@"category"]) { + if ([entry objectForKey:@"reference"]) { [fetchOnlyFieldsOfReferenceField addObject:@"uid"]; [fetchOnlyFieldsOfReferenceField addObject:@"_metadata"]; [fetchOnlyFieldsOfReferenceField addObject:@"_content_type_uid"]; - [[entry objectForKey:@"category"] enumerateObjectsUsingBlock:^(NSDictionary *obj, NSUInteger idx, BOOL * _Nonnull stop) { + [[entry objectForKey:@"reference"] enumerateObjectsUsingBlock:^(NSDictionary *obj, NSUInteger idx, BOOL * _Nonnull stop) { [[obj allKeys] enumerateObjectsUsingBlock:^(NSString *key, NSUInteger idx, BOOL * _Nonnull stop) { if (![fetchOnlyFieldsOfReferenceField containsObject:key]) { @@ -1563,11 +1563,11 @@ - (void)testFetchIncludeReferenceFieldWithKeyExcludingFields { XCTestExpectation *expectation = [self expectationWithDescription:@"Fetch Entries"]; - ContentType* csForm = [csStack contentTypeWithName:@"product"]; + ContentType* csForm = [csStack contentTypeWithName:@"source"]; Query* csQuery = [csForm query]; __block NSMutableArray *fetchExceptFieldsOfReferenceField = [NSMutableArray arrayWithArray:@[@"title"]]; - [csQuery includeReferenceFieldWithKey:@"category" excludingFields:fetchExceptFieldsOfReferenceField]; + [csQuery includeReferenceFieldWithKey:@"reference" excludingFields:fetchExceptFieldsOfReferenceField]; [csQuery find:^(ResponseType type, QueryResult *result, NSError *error) { @@ -1581,9 +1581,9 @@ - (void)testFetchIncludeReferenceFieldWithKeyExcludingFields { [self checkLanguageStatus:entry]; - if ([entry objectForKey:@"category"]) { + if ([entry objectForKey:@"reference"]) { - [[entry objectForKey:@"category"] enumerateObjectsUsingBlock:^(NSDictionary *obj, NSUInteger idx, BOOL * _Nonnull stop) { + [[entry objectForKey:@"reference"] enumerateObjectsUsingBlock:^(NSDictionary *obj, NSUInteger idx, BOOL * _Nonnull stop) { [[obj allKeys] enumerateObjectsUsingBlock:^(NSString *key, NSUInteger idx, BOOL * _Nonnull stop) { if ([fetchExceptFieldsOfReferenceField containsObject:key]) { @@ -1613,10 +1613,10 @@ - (void)testSearch { XCTestExpectation *expectation = [self expectationWithDescription:@"Search Entries"]; - ContentType* csForm = [csStack contentTypeWithName:@"product"]; + ContentType* csForm = [csStack contentTypeWithName:@"source"]; Query* csQuery = [csForm query]; - __block NSString *searchString = @"dress"; + __block NSString *searchString = @"source"; [csQuery search:searchString]; [csQuery find:^(ResponseType type, QueryResult *result, NSError *error) { @@ -1658,10 +1658,10 @@ - (void)testMatchRgex { XCTestExpectation *expectation = [self expectationWithDescription:@"Match Regex"]; - ContentType* csForm = [csStack contentTypeWithName:@"product"]; + ContentType* csForm = [csStack contentTypeWithName:@"source"]; Query* csQuery = [csForm query]; - __block NSString *regexString = @"\\wshirt"; + __block NSString *regexString = @"\\source"; [csQuery whereKey:@"title" matchesRegex:regexString]; [csQuery find:^(ResponseType type, QueryResult *result, NSError *error) { @@ -1691,10 +1691,10 @@ - (void)testMatchRgexWithModifier { XCTestExpectation *expectation = [self expectationWithDescription:@"Match Regex"]; - ContentType* csForm = [csStack contentTypeWithName:@"product"]; + ContentType* csForm = [csStack contentTypeWithName:@"source"]; Query* csQuery = [csForm query]; - __block NSString *regexString = @"\\wshirt"; + __block NSString *regexString = @"\\wsource"; [csQuery whereKey:@"title" matchesRegex:regexString modifiers:@"c"]; [csQuery find:^(ResponseType type, QueryResult *result, NSError *error) { @@ -1724,10 +1724,10 @@ - (void)testCaseForFindOne{ XCTestExpectation *expectation = [self expectationWithDescription:@"Find One Test"]; - ContentType* csForm = [csStack contentTypeWithName:@"product"]; + ContentType* csForm = [csStack contentTypeWithName:@"source"]; Query* csQuery = [csForm query]; - [csQuery whereKey:@"in_stock" equalTo:@(YES)]; + [csQuery whereKey:@"boolean" equalTo:@(YES)]; [csQuery findOne:^(ResponseType type, Entry *entry, NSError *error) { @@ -1737,7 +1737,7 @@ - (void)testCaseForFindOne{ [self checkLanguageStatus:entry]; - XCTAssertTrue(([entry valueForKey:@"in_stock"]), @"Values not available for specified key"); + XCTAssertTrue(([entry valueForKey:@"boolean"]), @"Values not available for specified key"); } [expectation fulfill]; @@ -1751,7 +1751,7 @@ - (void)testFetchWithContentType { XCTestExpectation *expectation = [self expectationWithDescription:@"Fetch Entries with Content type"]; - ContentType* csForm = [csStack contentTypeWithName:@"product"]; + ContentType* csForm = [csStack contentTypeWithName:@"source"]; Query* csQuery = [csForm query]; [csQuery includeContentType]; @@ -1780,7 +1780,7 @@ - (void)testFetchWithSchemaAndContentType { XCTestExpectation *expectation = [self expectationWithDescription:@"Fetch Entries with Schema & Content type"]; - ContentType* csForm = [csStack contentTypeWithName:@"product"]; + ContentType* csForm = [csStack contentTypeWithName:@"source"]; Query* csQuery = [csForm query]; [csQuery includeContentType]; @@ -1811,7 +1811,7 @@ - (void)testFetchWithIncludeReferenceContentTypeUID { XCTestExpectation *expectation = [self expectationWithDescription:@"Fetch Entries with Schema"]; - ContentType* csForm = [csStack contentTypeWithName:@"product"]; + ContentType* csForm = [csStack contentTypeWithName:@"source"]; Query* csQuery = [csForm query]; [csQuery includeReferenceContentTypeUid]; [csQuery find:^(ResponseType type, QueryResult *result, NSError *error) { @@ -1819,13 +1819,13 @@ - (void)testFetchWithIncludeReferenceContentTypeUID { XCTFail(@"~ ERR: %@", error.userInfo); } else { [[result getResult] enumerateObjectsUsingBlock:^(Entry *obj, NSUInteger idx, BOOL * _Nonnull stop) { - if ([[obj valueForKey:@"category"] isKindOfClass:[NSArray class]]) { - NSArray *catArray = [obj valueForKey:@"category"]; - for (id category in catArray) { - XCTAssertTrue([category isKindOfClass:[NSDictionary class]], "Category should be of type NSDictionary."); - if ([category isKindOfClass:[NSDictionary class]]) { - NSDictionary *catagoryDict = category; - XCTAssertTrue([catagoryDict.allKeys containsObject:@"_content_type_uid"], "Category should have '_content_type_uid' key."); + if ([[obj valueForKey:@"reference"] isKindOfClass:[NSArray class]]) { + NSArray *refArray = [obj valueForKey:@"reference"]; + for (id reference in refArray) { + XCTAssertTrue([reference isKindOfClass:[NSDictionary class]], "Category should be of type NSDictionary."); + if ([reference isKindOfClass:[NSDictionary class]]) { + NSDictionary *referenceDict = reference; + XCTAssertTrue([referenceDict.allKeys containsObject:@"_content_type_uid"], "Reference should have '_content_type_uid' key."); } } } @@ -1842,7 +1842,7 @@ - (void)testFetchWithContentTypeAndSchema { XCTestExpectation *expectation = [self expectationWithDescription:@"Fetch Entries with Content type & Schema"]; - ContentType* csForm = [csStack contentTypeWithName:@"product"]; + ContentType* csForm = [csStack contentTypeWithName:@"source"]; Query* csQuery = [csForm query]; [csQuery includeContentType]; @@ -1873,10 +1873,10 @@ - (void)testFetchTags { XCTestExpectation *expectation = [self expectationWithDescription:@"Fetch Tags"]; - ContentType* csForm = [csStack contentTypeWithName:@"product"]; + ContentType* csForm = [csStack contentTypeWithName:@"source"]; Query* csQuery = [csForm query]; - __block NSMutableArray *tags = [NSMutableArray arrayWithArray:@[@"women",@"men"]]; + __block NSMutableArray *tags = [NSMutableArray arrayWithArray:@[@"tags1",@"tags2"]]; [csQuery tags:tags]; [csQuery find:^(ResponseType type, QueryResult *result, NSError *error) { @@ -1920,11 +1920,11 @@ - (void)testFetchEntryForLanguage { XCTestExpectation *expectation = [self expectationWithDescription:@"Fetch Tags"]; - ContentType* csForm = [csStack contentTypeWithName:@"product"]; + ContentType* csForm = [csStack contentTypeWithName:@"source"]; Query* csQuery = [csForm query]; [csQuery locale:@"en-us"]; - [csQuery whereKey:@"uid" equalTo:_productUid]; + [csQuery whereKey:@"uid" equalTo:_sourceUid]; [csQuery find:^(ResponseType type, QueryResult *result, NSError *error) { @@ -1957,9 +1957,9 @@ - (void)testFetchLimitedEntries { XCTestExpectation *expectation = [self expectationWithDescription:@"Fetch Tags"]; - ContentType* csForm = [csStack contentTypeWithName:@"product"]; + ContentType* csForm = [csStack contentTypeWithName:@"source"]; - __block NSInteger objectLimit = 10; + __block NSInteger objectLimit = 4; Query* csQuery = [csForm query]; [csQuery limitObjects:@(objectLimit)]; @@ -1983,9 +1983,9 @@ - (void)testFetchSkipEntries { XCTestExpectation *expectation = [self expectationWithDescription:@"Fetch Tags"]; - ContentType* csForm = [csStack contentTypeWithName:@"product"]; + ContentType* csForm = [csStack contentTypeWithName:@"source"]; - __block NSInteger skipObject = 10; + __block NSInteger skipObject = 4; Query* csQuery = [csForm query]; [csQuery includeCount]; [csQuery skipObjects:@(skipObject)]; @@ -1996,7 +1996,7 @@ - (void)testFetchSkipEntries { XCTFail(@"~ ERR: %@", error.userInfo); } else { - XCTAssertTrue(([result totalCount]-skipObject) <= [result getResult].count, "query should skip 10 objects"); + XCTAssertTrue(([result totalCount]-skipObject) <= [result getResult].count, "query should skip 4 objects"); } [expectation fulfill]; @@ -2011,7 +2011,7 @@ - (void)testFetchIncludeCount { XCTestExpectation *expectation = [self expectationWithDescription:@"Fetch Include Count"]; - ContentType* csForm = [csStack contentTypeWithName:@"product"]; + ContentType* csForm = [csStack contentTypeWithName:@"source"]; Query* csQuery = [csForm query]; [csQuery includeCount]; @@ -2038,7 +2038,7 @@ - (void)testFetchLongQuery { XCTestExpectation *expectation = [self expectationWithDescription:@"Fetch Long Query"]; - ContentType* csForm = [csStack contentTypeWithName:@"product"]; + ContentType* csForm = [csStack contentTypeWithName:@"source"]; Query* csQuery = [csForm query]; @@ -2065,10 +2065,10 @@ - (void)testFetchAddQuery { XCTestExpectation *expectation = [self expectationWithDescription:@"Test Add Query"]; - ContentType* csForm = [csStack contentTypeWithName:@"product"]; + ContentType* csForm = [csStack contentTypeWithName:@"source"]; Query* csQuery = [csForm query]; - [csQuery addQueryWithKey:@"query" andValue:@{ @"price":@{@"$gte": @(99)}}]; + [csQuery addQueryWithKey:@"query" andValue:@{ @"number":@{@"$gte": @(99)}}]; [csQuery find:^(ResponseType type, QueryResult *result, NSError *error) { @@ -2080,7 +2080,7 @@ - (void)testFetchAddQuery { for (Entry *entry in [result getResult]) { [self checkLanguageStatus:entry]; - XCTAssertTrue(([[entry objectForKey:@"price"] integerValue] >= 99), @"condition not specified for query"); + XCTAssertTrue(([[entry objectForKey:@"number"] integerValue] >= 99), @"condition not specified for query"); } } [expectation fulfill]; @@ -2093,10 +2093,10 @@ - (void)testFetchRemoveQuery { XCTestExpectation *expectation = [self expectationWithDescription:@"Test Add Query"]; - ContentType* csForm = [csStack contentTypeWithName:@"product"]; + ContentType* csForm = [csStack contentTypeWithName:@"source"]; Query* csQuery = [csForm query]; - [csQuery addQueryWithKey:@"query" andValue:@{ @"price":@{@"$gte": @(99)}}]; + [csQuery addQueryWithKey:@"query" andValue:@{ @"number":@{@"$gte": @(99)}}]; [csQuery removeQueryWithKey:@"query"]; [csQuery includeCount]; @@ -2122,15 +2122,15 @@ - (void)testFetchRemoveQuery { - (void)testReferenceIn { XCTestExpectation *expectation = [self expectationWithDescription:@"Test Add Query"]; - ContentType* csForm = [csStack contentTypeWithName:@"product"]; + ContentType* csForm = [csStack contentTypeWithName:@"source"]; Query* referenceQuery = [csForm query]; - [referenceQuery whereKey:@"title" equalTo:@"Women"]; + [referenceQuery whereKey:@"title" equalTo:@"source"]; Query* csQuery = [csForm query]; - [csQuery includeReferenceFieldWithKey:@[@"category"]]; - [csQuery whereKey:@"category" in:referenceQuery]; + [csQuery includeReferenceFieldWithKey:@[@"reference"]]; + [csQuery whereKey:@"reference" in:referenceQuery]; [csQuery find:^(ResponseType type, QueryResult *result, NSError *error) { @@ -2142,7 +2142,7 @@ - (void)testReferenceIn { if ([obj isKindOfClass:[Entry class]]) { [self checkLanguageStatus:obj]; - XCTAssertTrue([[[obj objectForKey:@"category"] valueForKey:@"title"] containsObject:@"Women"],@"Title is not equal"); + XCTAssertTrue([[[obj objectForKey:@"reference"] valueForKey:@"title"] containsObject:@"source"],@"Title is not equal"); } }]; } @@ -2156,14 +2156,14 @@ - (void)testReferenceIn { - (void)testReferenceNotIn { XCTestExpectation *expectation = [self expectationWithDescription:@"Test Add Query"]; - ContentType* csForm = [csStack contentTypeWithName:@"product"]; + ContentType* csForm = [csStack contentTypeWithName:@"source"]; Query* referenceQuery = [csForm query]; - [referenceQuery whereKey:@"title" equalTo:@"Women"]; + [referenceQuery whereKey:@"title" equalTo:@"source"]; Query* csQuery = [csForm query]; [csQuery includeReferenceFieldWithKey:@[@"category"]]; - [csQuery whereKey:@"category" notIn:referenceQuery]; + [csQuery whereKey:@"reference" notIn:referenceQuery]; [csQuery find:^(ResponseType type, QueryResult *result, NSError *error) { @@ -2173,7 +2173,7 @@ - (void)testReferenceNotIn { [[result getResult] enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { if ([obj isKindOfClass:[Entry class]]) { if ([obj objectForKey:@"category"] != nil && [[obj objectForKey:@"category"] valueForKey:@"title"] != nil) { - XCTAssertTrue(![[[obj objectForKey:@"category"] valueForKey:@"title"] containsObject:@"Women"],@"Title is equal"); + XCTAssertTrue(![[[obj objectForKey:@"reference"] valueForKey:@"title"] containsObject:@"source"],@"Title is equal"); } } }]; @@ -2247,7 +2247,7 @@ - (void)testaddParamForAsset { - (void)testaddParamForQuery { XCTestExpectation *expectation = [self expectationWithDescription:@"Fetch Greater than Entries"]; - ContentType* csForm = [csStack contentTypeWithName:@"product"]; + ContentType* csForm = [csStack contentTypeWithName:@"source"]; Query* csQuery = [csForm query]; [csQuery addParamKey:@"limit" andValue:@"1"]; [csQuery find:^(ResponseType type, QueryResult *result, NSError *error) { @@ -2267,4 +2267,90 @@ - (void)testaddParamForQuery { [self waitForRequest]; } +- (void)testFetchTaxonomyEntries { + XCTestExpectation *expectation = [self expectationWithDescription:@"Fetch all taxonomy entries"]; + Taxonomy *csForm = [csStack taxonomy]; + Query *csQuery = [csForm query]; + NSDictionary *queryDictionary = @{@"taxonomies.one": @"term_one"}; + [csQuery query:queryDictionary]; + [csQuery findTaxonomy:^(ResponseType type, QueryResult *result, NSError *error) { + XCTAssert(type == NETWORK, @"Pass"); + if (error) { + XCTFail(@"~ ERR: %@", error.userInfo); + } else { + [self testProductCount:[result getResult]]; + if ([result getResult].count == 2) { + XCTAssert(YES, @"Pass"); + } else { + XCTFail(@"wrong taxonomy object"); + } + } + [expectation fulfill]; + }]; + + [self waitForRequest]; +} + +- (void)testFetchTaxonomyEntriesWithOr { + XCTestExpectation *expectation = [self expectationWithDescription:@"Fetch all taxonomy entries with or query"]; + Taxonomy *csForm = [csStack taxonomy]; + + Query *query1 = [csForm query]; + [query1 whereKey:@"taxonomies.one" equalTo:@"term_one"]; + + Query *query2 = [csForm query]; + [query1 whereKey:@"taxonomies.two" equalTo:@"term_two"]; + + Query* csQuery = [csForm query]; + [csQuery orWithSubqueries:@[query1, query2]]; + + [csQuery findTaxonomy:^(ResponseType type, QueryResult *result, NSError *error) { + XCTAssert(type == NETWORK, @"Pass"); + if (error) { + XCTFail(@"~ ERR: %@", error.userInfo); + } else { + [self testProductCount:[result getResult]]; + if ([result getResult].count == 2) { + XCTAssert(YES, @"Pass"); + } else { + XCTFail(@"wrong taxonomy object"); + } + } + [expectation fulfill]; + }]; + + [self waitForRequest]; +} + +- (void)testFetchTaxonomyEntriesWithAnd { + XCTestExpectation *expectation = [self expectationWithDescription:@"Fetch all taxonomy entries with and query"]; + Taxonomy *csForm = [csStack taxonomy]; + + Query *query1 = [csForm query]; + [query1 whereKey:@"taxonomies.one" equalTo:@"term_one"]; + + Query *query2 = [csForm query]; + [query1 whereKey:@"taxonomies.two" equalTo:@"term_two"]; + + Query* csQuery = [csForm query]; + [csQuery andWithSubqueries:@[query1, query2]]; + + [csQuery findTaxonomy:^(ResponseType type, QueryResult *result, NSError *error) { + XCTAssert(type == NETWORK, @"Pass"); + if (error) { + XCTFail(@"~ ERR: %@", error.userInfo); + } else { + [self testProductCount:[result getResult]]; + if ([result getResult].count == 2) { + XCTAssert(YES, @"Pass"); + } else { + XCTFail(@"wrong taxonomy object"); + } + } + [expectation fulfill]; + }]; + + [self waitForRequest]; +} + @end diff --git a/ContentstackTest/SyncTest.m b/ContentstackTest/SyncTest.m index 621c108..fdb9f34 100644 --- a/ContentstackTest/SyncTest.m +++ b/ContentstackTest/SyncTest.m @@ -115,10 +115,10 @@ - (void)testSyncPublishType { - (void)testSyncOnlyClass { XCTestExpectation *expectation = [self expectationWithDescription:@"SyncOnlyClass"]; - [csStack syncOnly:@"product" completion:^(SyncStack * _Nullable syncStack, NSError * _Nullable error) { + [csStack syncOnly:@"source" completion:^(SyncStack * _Nullable syncStack, NSError * _Nullable error) { for (NSDictionary *item in syncStack.items) { if ([[item objectForKey:@"content_type_uid"] isKindOfClass:[NSString class]]) { - XCTAssertTrue([[item objectForKey:@"content_type_uid"] isEqualToString:@"product"]); + XCTAssertTrue([[item objectForKey:@"content_type_uid"] isEqualToString:@"source"]); } } if (syncStack.syncToken != nil) { @@ -129,10 +129,10 @@ - (void)testSyncOnlyClass { -(void)testSyncOnlyWithLocale { XCTestExpectation *expectation = [self expectationWithDescription:@"SyncOnlyWithLocale"]; - [csStack syncOnly:@"product" locale:@"en-us" from:nil completion:^(SyncStack * _Nullable syncStack, NSError * _Nullable error) { + [csStack syncOnly:@"source" locale:@"en-us" from:nil completion:^(SyncStack * _Nullable syncStack, NSError * _Nullable error) { for (NSDictionary *item in syncStack.items) { if ([[item objectForKey:@"content_type_uid"] isKindOfClass:[NSString class]]) { - XCTAssertTrue([[item objectForKey:@"content_type_uid"] isEqualToString:@"product"]); + XCTAssertTrue([[item objectForKey:@"content_type_uid"] isEqualToString:@"source"]); } if ([[item objectForKey:@"data"] isKindOfClass:[NSDictionary class]]) { NSDictionary *data = [item objectForKey:@"data"]; @@ -152,10 +152,10 @@ - (void)testSyncOnlyClassAndDate { NSDate *date = [NSDate dateWithTimeIntervalSince1970:1534617000]; XCTestExpectation *expectation = [self expectationWithDescription:@"SyncOnlyClassAndDate"]; - [csStack syncOnly:@"product" from:date completion:^(SyncStack * _Nullable syncStack, NSError * _Nullable error) { + [csStack syncOnly:@"source" from:date completion:^(SyncStack * _Nullable syncStack, NSError * _Nullable error) { for (NSDictionary *item in syncStack.items) { if ([[item objectForKey:@"content_type_uid"] isKindOfClass:[NSString class]]) { - XCTAssertTrue([[item objectForKey:@"content_type_uid"] isEqualToString:@"product"]); + XCTAssertTrue([[item objectForKey:@"content_type_uid"] isEqualToString:@"source"]); } if ([[item objectForKey:@"event_at"] isKindOfClass:[NSString class]]) { NSDate *daatee = [formatter dateFromString:[[item objectForKey:@"event_at"] stringByReplacingOccurrencesOfString:@"." withString:@""]]; diff --git a/Podfile.lock b/Podfile.lock index fc2a5f5..5ff1e1c 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -1,3 +1,3 @@ PODFILE CHECKSUM: e70b33906e829ccd2b052bc0e0cff91ee8ee49e6 -COCOAPODS: 1.15.0 +COCOAPODS: 1.14.3 diff --git a/README.md b/README.md index e4b4ac5..09dc4dd 100644 --- a/README.md +++ b/README.md @@ -300,7 +300,7 @@ You can use advanced sync queries to fetch custom results while performing initi ### The MIT License (MIT) -Copyright © 2012-2022 [Contentstack](https://www.contentstack.com/). All Rights Reserved +Copyright © 2012-2024 [Contentstack](https://www.contentstack.com/). All Rights Reserved Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: