From 29e50f2ea8fbc90013518c8b246a9db7585969c9 Mon Sep 17 00:00:00 2001
From: Gabriel Omar Cotelli <g.cotelli@gmail.com>
Date: Wed, 25 Nov 2020 19:27:14 -0300
Subject: [PATCH 1/3] Introduce generic set header command

---
 .../HttpRequestTest.class.st                  | 22 +++++++++++++++
 ...class.st => SetHeaderCommandTest.class.st} | 10 +++----
 .../HttpRequestHeadersBuilder.class.st        | 10 +++++--
 ...and.class.st => SetHeaderCommand.class.st} | 28 ++++++++++++-------
 .../RESTfulAPIClient.class.st                 | 18 ++++++++----
 5 files changed, 65 insertions(+), 23 deletions(-)
 rename source/Superluminal-Model-Tests/{SetAuthorizationHeaderCommandTest.class.st => SetHeaderCommandTest.class.st} (60%)
 rename source/Superluminal-Model/{SetAuthorizationHeaderCommand.class.st => SetHeaderCommand.class.st} (63%)

diff --git a/source/Superluminal-Model-Tests/HttpRequestTest.class.st b/source/Superluminal-Model-Tests/HttpRequestTest.class.st
index 1c6b4d3..125bb27 100644
--- a/source/Superluminal-Model-Tests/HttpRequestTest.class.st
+++ b/source/Superluminal-Model-Tests/HttpRequestTest.class.st
@@ -163,6 +163,28 @@ HttpRequestTest >> testGetWithAuthorization [
 			]
 ]
 
+{ #category : #tests }
+HttpRequestTest >> testGetWithCustomHeader [
+
+	| httpRequest response |
+
+	httpRequest := HttpRequest
+		get: self httpbinLocation
+		configuredUsing: [ :request | request headers set: #XXXX to: 'Yes' ].
+
+	response := httpRequest applyOn: self newHttpClient.
+
+	self
+		assert: response isSuccess;
+		withJsonFromContentsIn: response
+			do: [ :json | 
+			self
+				assert: json url equals: self httpbinLocation;
+				assert: json method equals: 'GET';
+				assert: json headers XXXX equals: 'Yes'
+			]
+]
+
 { #category : #tests }
 HttpRequestTest >> testGetWithEmptyConfiguration [
 
diff --git a/source/Superluminal-Model-Tests/SetAuthorizationHeaderCommandTest.class.st b/source/Superluminal-Model-Tests/SetHeaderCommandTest.class.st
similarity index 60%
rename from source/Superluminal-Model-Tests/SetAuthorizationHeaderCommandTest.class.st
rename to source/Superluminal-Model-Tests/SetHeaderCommandTest.class.st
index 81e1549..4ab3802 100644
--- a/source/Superluminal-Model-Tests/SetAuthorizationHeaderCommandTest.class.st
+++ b/source/Superluminal-Model-Tests/SetHeaderCommandTest.class.st
@@ -1,26 +1,26 @@
 Class {
-	#name : #SetAuthorizationHeaderCommandTest,
+	#name : #SetHeaderCommandTest,
 	#superclass : #TestCase,
 	#category : #'Superluminal-Model-Tests-Commands'
 }
 
 { #category : #tests }
-SetAuthorizationHeaderCommandTest >> testApplyOn [
+SetHeaderCommandTest >> testApplyOn [
 
 	| httpClient command |
 
 	httpClient := ZnClient new.
-	command := SetAuthorizationHeaderCommand toBearerToken:  'token'.
+	command := SetHeaderCommand settingAuthorizationToBearerToken:  'token'.
 	command applyOn: httpClient.
 
 	self assert: ( httpClient request headers at: #Authorization ) equals: 'Bearer ''token'''
 ]
 
 { #category : #tests }
-SetAuthorizationHeaderCommandTest >> testCannotUseAnEmptyValue [
+SetHeaderCommandTest >> testCannotUseAnEmptyValue [
 
 	self
-		should: [ SetAuthorizationHeaderCommand to: '' ]
+		should: [ SetHeaderCommand settingAuthorizationTo: '' ]
 		raise: InstanceCreationFailed
 		withMessageText: 'An Authorization header cannot include empty directives.'
 ]
diff --git a/source/Superluminal-Model/HttpRequestHeadersBuilder.class.st b/source/Superluminal-Model/HttpRequestHeadersBuilder.class.st
index 8b03508..f3355ba 100644
--- a/source/Superluminal-Model/HttpRequestHeadersBuilder.class.st
+++ b/source/Superluminal-Model/HttpRequestHeadersBuilder.class.st
@@ -4,6 +4,12 @@ Class {
 	#category : #'Superluminal-Model-Builders'
 }
 
+{ #category : #configuring }
+HttpRequestHeadersBuilder >> set: aHeaderName to: aHeaderValue [
+
+	^ SetHeaderCommand setting: aHeaderName to: aHeaderValue
+]
+
 { #category : #configuring }
 HttpRequestHeadersBuilder >> setAcceptTo: aMediaType [
 	
@@ -13,13 +19,13 @@ HttpRequestHeadersBuilder >> setAcceptTo: aMediaType [
 { #category : #configuring }
 HttpRequestHeadersBuilder >> setAuthorizationTo: anAuthorizationDirective [
 
-	^ SetAuthorizationHeaderCommand to: anAuthorizationDirective
+	^ SetHeaderCommand settingAuthorizationTo: anAuthorizationDirective
 ]
 
 { #category : #configuring }
 HttpRequestHeadersBuilder >> setBearerTokenTo: aBearerToken [
 
-	^ SetAuthorizationHeaderCommand toBearerToken: aBearerToken
+	^ SetHeaderCommand settingAuthorizationToBearerToken: aBearerToken
 ]
 
 { #category : #configuring }
diff --git a/source/Superluminal-Model/SetAuthorizationHeaderCommand.class.st b/source/Superluminal-Model/SetHeaderCommand.class.st
similarity index 63%
rename from source/Superluminal-Model/SetAuthorizationHeaderCommand.class.st
rename to source/Superluminal-Model/SetHeaderCommand.class.st
index 746f4e3..2152b77 100644
--- a/source/Superluminal-Model/SetAuthorizationHeaderCommand.class.st
+++ b/source/Superluminal-Model/SetHeaderCommand.class.st
@@ -12,39 +12,47 @@ Directives
 
 "
 Class {
-	#name : #SetAuthorizationHeaderCommand,
+	#name : #SetHeaderCommand,
 	#superclass : #HttpRequestCommand,
 	#instVars : [
-		'authorizationDirectives'
+		'headerName',
+		'headerValue'
 	],
 	#category : #'Superluminal-Model-Commands'
 }
 
 { #category : #'instance creation' }
-SetAuthorizationHeaderCommand class >> to: anAuthorizationDirective [
+SetHeaderCommand class >> setting: aHeaderName to: aHeaderValue [
+
+	^ self new initializeSetting: aHeaderName to: aHeaderValue
+]
+
+{ #category : #'instance creation' }
+SetHeaderCommand class >> settingAuthorizationTo: anAuthorizationDirective [
 
 	AssertionChecker
 		enforce: [ anAuthorizationDirective notEmpty ]
 		because: 'An Authorization header cannot include empty directives.'
 		raising: InstanceCreationFailed.
 
-	^ self new initializeTo: anAuthorizationDirective
+	^ self new initializeSetting: #Authorization to: anAuthorizationDirective
 ]
 
 { #category : #'instance creation' }
-SetAuthorizationHeaderCommand class >> toBearerToken: token [
+SetHeaderCommand class >> settingAuthorizationToBearerToken: token [
 
-	^ self to: ( #'Bearer <1p>' expandMacrosWith: token )
+	^ self settingAuthorizationTo: ( #'Bearer <1p>' expandMacrosWith: token )
 ]
 
 { #category : #applying }
-SetAuthorizationHeaderCommand >> applyOn: httpClient [
+SetHeaderCommand >> applyOn: httpClient [
 
-	httpClient headerAt: #Authorization put: authorizationDirectives
+	httpClient headerAt: headerName put: headerValue
 ]
 
 { #category : #initialization }
-SetAuthorizationHeaderCommand >> initializeTo: anAuthorizationDirective [
+SetHeaderCommand >> initializeSetting: aHeaderName to: aHeaderValue [
 
-	authorizationDirectives := anAuthorizationDirective
+	headerName := aHeaderName.
+	headerValue := aHeaderValue
 ]
diff --git a/source/Superluminal-RESTfulAPI/RESTfulAPIClient.class.st b/source/Superluminal-RESTfulAPI/RESTfulAPIClient.class.st
index b9abb68..9d9cc5f 100644
--- a/source/Superluminal-RESTfulAPI/RESTfulAPIClient.class.st
+++ b/source/Superluminal-RESTfulAPI/RESTfulAPIClient.class.st
@@ -212,17 +212,23 @@ RESTfulAPIClient >> patch: anEntity at: aLocation withSuccessfulResponseDo: aBlo
 RESTfulAPIClient >> post: anEntity at: aLocation withSuccessfulResponseDo: aBlock [
 
 	^ self
-		handleExceptionsDuring: [ | httpRequest response |
+		postAt: aLocation
+		configuredBy: [ :request | request body contents: anEntity ]
+		withSuccessfulResponseDo: aBlock
+]
 
-			httpRequest := HttpRequest
-				post: aLocation
-				configuredUsing: [ :request | request body contents: anEntity ].
+{ #category : #invoking }
+RESTfulAPIClient >> postAt: aLocation configuredBy: aRequestBuildingBlock withSuccessfulResponseDo: aBlock [
+
+	^ self
+		handleExceptionsDuring: [ 
+			| httpRequest response |
+			httpRequest := HttpRequest post: aLocation configuredUsing: aRequestBuildingBlock.
 			self
 				withHttpClientFor: aLocation
 				do: [ :httpClient | response := httpRequest applyOn: httpClient ].
 			response isSuccess
-				ifTrue: [ 
-					expiringCache clearResourceAt: aLocation.
+				ifTrue: [ expiringCache clearResourceAt: aLocation.
 					response isCreated then: [ self tryToCacheContentsOf: response basedOn: response location ].
 					aBlock value: response contents
 					]

From cceb9e035b0493aea1eb15a81428fb9ed1015223 Mon Sep 17 00:00:00 2001
From: Gabriel Omar Cotelli <g.cotelli@gmail.com>
Date: Wed, 25 Nov 2020 19:29:13 -0300
Subject: [PATCH 2/3] Reuse method

---
 source/Superluminal-Model/SetHeaderCommand.class.st | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/source/Superluminal-Model/SetHeaderCommand.class.st b/source/Superluminal-Model/SetHeaderCommand.class.st
index 2152b77..880638d 100644
--- a/source/Superluminal-Model/SetHeaderCommand.class.st
+++ b/source/Superluminal-Model/SetHeaderCommand.class.st
@@ -35,7 +35,7 @@ SetHeaderCommand class >> settingAuthorizationTo: anAuthorizationDirective [
 		because: 'An Authorization header cannot include empty directives.'
 		raising: InstanceCreationFailed.
 
-	^ self new initializeSetting: #Authorization to: anAuthorizationDirective
+	^ self setting: #Authorization to: anAuthorizationDirective
 ]
 
 { #category : #'instance creation' }

From 6a168f5d46ee302291ab2f8d59441fa5c2f4b8c8 Mon Sep 17 00:00:00 2001
From: Gabriel Omar Cotelli <g.cotelli@gmail.com>
Date: Wed, 25 Nov 2020 19:54:23 -0300
Subject: [PATCH 3/3] Fix test

---
 source/Superluminal-Model-Tests/HttpRequestTest.class.st | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/source/Superluminal-Model-Tests/HttpRequestTest.class.st b/source/Superluminal-Model-Tests/HttpRequestTest.class.st
index 125bb27..011ee11 100644
--- a/source/Superluminal-Model-Tests/HttpRequestTest.class.st
+++ b/source/Superluminal-Model-Tests/HttpRequestTest.class.st
@@ -170,7 +170,7 @@ HttpRequestTest >> testGetWithCustomHeader [
 
 	httpRequest := HttpRequest
 		get: self httpbinLocation
-		configuredUsing: [ :request | request headers set: #XXXX to: 'Yes' ].
+		configuredUsing: [ :request | request headers set: #Authorization to: 'Yes' ].
 
 	response := httpRequest applyOn: self newHttpClient.
 
@@ -181,7 +181,7 @@ HttpRequestTest >> testGetWithCustomHeader [
 			self
 				assert: json url equals: self httpbinLocation;
 				assert: json method equals: 'GET';
-				assert: json headers XXXX equals: 'Yes'
+				assert: json headers Authorization equals: 'Yes'
 			]
 ]