Skip to content

Commit

Permalink
Merge pull request #26 from algolia/feat/extra-query-params
Browse files Browse the repository at this point in the history
Allow extra query parameters to be specified
  • Loading branch information
Clément Le Provost committed Apr 8, 2016
2 parents 1232a4a + 37e79c6 commit 3aada92
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 0 deletions.
25 changes: 25 additions & 0 deletions src/ASQuery.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,31 @@
*/
-(NSString*) buildURL;

/**
* Set a parameter by name and string value.
*
* WARNING: Parameters set this way override any conflicting typed property. No consistency check is performed.
* Whenever available, the typed property should be preferred.
*/
- (void)set:(NSString * _Nonnull)name value:(NSString * _Nullable)value;

/**
* Get the value of an extra parameter.
*
* WARNING: Only parameters set using `-[ASQuery set:value:]` (or the subscript operator) can be read this way.
*/
- (NSString * _Nullable)get:(NSString * _Nonnull)name;

/**
* Subscript assignment operator. Convenience shortcut for `-[ASQuery set:value:]`.
*/
- (void)setObject:(NSString * _Nullable)newValue forKeyedSubscript:(NSString * _Nonnull)index;

/**
* Subscript read operator. Convenience shortcut for `-[ASQuery get:]`.
*/
- (NSString * _Nullable)objectForKeyedSubscript:(NSString * _Nonnull)index;

/**
* Select how the query words are interpreted:
* "prefixAll": all query words are interpreted as prefixes,
Expand Down
31 changes: 31 additions & 0 deletions src/ASQuery.m
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ @implementation ASQuery {
BOOL advancedSyntaxSet;
BOOL removeStopWordsSet;
BOOL maxValuesPerFacetSet;
NSMutableDictionary<NSString*, NSString*>* _parameters;
}

+(instancetype) queryWithFullTextQuery:(NSString *)fullTextQuery
Expand All @@ -59,6 +60,7 @@ -(instancetype) initWithFullTextQuery:(NSString *)pfullTextQuery
{
self = [super init];
if (self) {
_parameters = [NSMutableDictionary dictionary];
minWordSizeForApprox1Set = minWordSizeForApprox2Set = getRankingInfoSet = ignorePluralSet = distinctSet = hitsPerPageSet = minProximitySet = maxValuesPerFacetSet = NO;
typosOnNumericTokensSet = analyticsSet = synonymsSet = replaceSynonymsSet = optionalWordsMinimumMatchedSet = aroundLatLongViaIPSet = NO;
advancedSyntaxSet = removeStopWordsSet = aroundPrecisionSet = aroundRadiusSet = NO;
Expand Down Expand Up @@ -96,6 +98,7 @@ -(instancetype) initWithFullTextQuery:(NSString *)pfullTextQuery
-(instancetype) copyWithZone:(NSZone*)zone {
ASQuery *new = [[ASQuery alloc] init];

new->_parameters = [NSMutableDictionary dictionaryWithDictionary:self->_parameters];
if (minWordSizeForApprox1Set)
new.minWordSizeForApprox1 = self.minWordSizeForApprox1;
if (minWordSizeForApprox2Set)
Expand Down Expand Up @@ -513,10 +516,38 @@ -(NSString*) buildURL
[stringBuilder appendString:@"&"];
[stringBuilder appendFormat:@"maxValuesPerFacet=%zd", self.maxValuesPerFacet];
}
// WARNING: Any extra parameter will override any previous one with the same name.
for (NSString* name in _parameters) {
if ([stringBuilder length] > 0)
[stringBuilder appendString:@"&"];
[stringBuilder appendString:[ASAPIClient urlEncode:name]];
[stringBuilder appendString:@"="];
[stringBuilder appendString:[ASAPIClient urlEncode:[_parameters objectForKey:name]]];
}

return stringBuilder;
}

- (void)set:(NSString * _Nonnull)name value:(NSString * _Nullable)value {
if (value == nil) {
[_parameters removeObjectForKey:name];
} else {
[_parameters setObject:value forKey:name];
}
}

- (NSString * _Nullable)get:(NSString * _Nonnull)name {
return [_parameters objectForKey:name];
}

- (void)setObject:(NSString * _Nullable)newValue forKeyedSubscript:(NSString * _Nonnull)index {
[self set:index value:newValue];
}

- (NSString * _Nullable)objectForKeyedSubscript:(NSString * _Nonnull)index {
return [self get:index];
}

@synthesize minWordSizeForApprox1 = _minWordSizeForApprox1;
-(void) setMinWordSizeForApprox1:(NSUInteger)minWordSizeForApprox1 {
_minWordSizeForApprox1 = minWordSizeForApprox1;
Expand Down
45 changes: 45 additions & 0 deletions test/test.m
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,51 @@ - (void)tearDown
[self waitForExpectationsWithTimeout:1000 handler:nil];
}

- (void)testQueryExtraParameters
{
// Accessor methods.
{
ASQuery* query = [[ASQuery alloc] init];
[query set:@"extra" value:@"value"];
XCTAssertEqualObjects([query get:@"extra"], @"value");
XCTAssertEqualObjects([query buildURL], @"extra=value");
[query set:@"abc" value:@"def"];
NSString* url = [query buildURL];
XCTAssert([url isEqualToString:@"abc=def&extra=value"] || [url isEqualToString:@"extra=value&abc=def"]);
}
// Subscripting.
{
ASQuery* query = [[ASQuery alloc] init];
query[@"extra"] = @"value";
XCTAssertEqualObjects(query[@"extra"], @"value");
XCTAssertEqualObjects([query buildURL], @"extra=value");
query[@"abc"] = @"def";
NSString* url = [query buildURL];
XCTAssert([url isEqualToString:@"abc=def&extra=value"] || [url isEqualToString:@"extra=value&abc=def"]);
}
// Percent escaping.
{
ASQuery* query = [[ASQuery alloc] init];
query[@"%&="] = @"àéïôù";
XCTAssertEqualObjects([query buildURL], @"%25%26%3D=%C3%A0%C3%A9%C3%AF%C3%B4%C3%B9");
}
// Overriding a typed query parameter.
{
ASQuery* query = [[ASQuery alloc] init];
query.hitsPerPage = 100;
query[@"hitsPerPage"] = @"666";
XCTAssertEqualObjects([query buildURL], @"hitsPerPage=100&hitsPerPage=666");
}
// Deleting a parameter.
{
ASQuery* query = [[ASQuery alloc] init];
query[@"abc"] = @"ABC";
query[@"def"] = @"DEF";
query[@"abc"] = nil;
XCTAssertEqualObjects([query buildURL], @"def=DEF");
}
}

- (void)testQueryErrorHandling
{
XCTestExpectation *notFoundExpectation = [self expectationWithDescription:@"ressourceDoesNotExist"];
Expand Down

0 comments on commit 3aada92

Please sign in to comment.