RESTClient improvements and LiveTest adjustments

This commit is contained in:
João Antônio Duarte 2020-09-17 20:06:24 -03:00
parent ff5aefbd15
commit b21096b515
4 changed files with 69 additions and 56 deletions

View File

@ -37,6 +37,7 @@ uses
JsonDataObjects,
MVCFramework.Commons,
MVCFramework.Serializer.Commons,
MVCFramework.RESTClient.Intf,
MVCFramework.RESTClient;
type
@ -132,14 +133,14 @@ type
type
TMVCAPIBinderItem = class
private
fRESTClient: TRESTClient;
fRESTClient: IMVCRESTClient;
fDataSet: TDataSet;
fURI: string;
fPrimaryKeyNAme: string;
fLoading: boolean;
procedure ShowError(const AResponse: IRESTResponse);
procedure ShowError(const AResponse: IMVCRESTResponse);
public
constructor Create(const aRESTClient: TRESTClient; const ADataSet: TDataSet;
constructor Create(const aRESTClient: IMVCRESTClient; const ADataSet: TDataSet;
const aURI, aPrimaryKeyName: string);
destructor Destroy; override;
procedure HookBeforePost(DataSet: TDataSet);
@ -149,12 +150,12 @@ type
// procedure HookBeforeRowRequest(DataSet: TFDDataSet);
end;
private
fRESTClient: TRESTClient;
fRESTClient: IMVCRESTClient;
protected
fItems: TObjectList<TMVCAPIBinderItem>;
public
constructor Create(const aRESTClient: TRESTClient);
constructor Create(const aRESTClient: IMVCRESTClient);
destructor Destroy; override;
procedure BindDataSetToAPI(const ADataSet: TDataSet; const aURI: string; const aPrimaryKeyName: string);
end;
@ -597,7 +598,7 @@ begin
fItems.Add(TMVCAPIBinderItem.Create(fRESTClient, ADataSet, aURI, aPrimaryKeyName));
end;
constructor TMVCAPIBinder.Create(const aRESTClient: TRESTClient);
constructor TMVCAPIBinder.Create(const aRESTClient: IMVCRESTClient);
begin
inherited Create;
fItems := TObjectList<TMVCAPIBinderItem>.Create(true);
@ -612,7 +613,7 @@ end;
{ TMVCAPIBinder.TMVCAPIBinderItem }
constructor TMVCAPIBinder.TMVCAPIBinderItem.Create(const aRESTClient: TRESTClient; const ADataSet: TDataSet;
constructor TMVCAPIBinder.TMVCAPIBinderItem.Create(const aRESTClient: IMVCRESTClient; const ADataSet: TDataSet;
const aURI, aPrimaryKeyName: string);
begin
inherited Create;
@ -640,18 +641,18 @@ end;
procedure TMVCAPIBinder.TMVCAPIBinderItem.HookAfterOpen(DataSet: TDataSet);
var
Res: IRESTResponse;
Res: IMVCRESTResponse;
lData: TJSONObject;
begin
// this a simple sychronous request...
Res := fRESTClient.doGET(fURI, []);
if Res.HasError then
Res := fRESTClient.Get(fURI);
if Res.Success then
begin
ShowError(Res);
end;
lData := StrToJSONObject(Res.BodyAsString);
lData := StrToJSONObject(Res.Content);
try
DataSet.DisableControls;
try
@ -669,11 +670,11 @@ end;
procedure TMVCAPIBinder.TMVCAPIBinderItem.HookBeforeDelete(DataSet: TDataSet);
var
Res: IRESTResponse;
Res: IMVCRESTResponse;
begin
if DataSet.State = dsBrowse then
Res := fRESTClient.DataSetDelete(fURI, DataSet.FieldByName(fPrimaryKeyNAme).AsString);
if not(Res.ResponseCode in [200]) then
if not(Res.StatusCode in [200]) then
begin
ShowError(Res);
end;
@ -681,7 +682,7 @@ end;
procedure TMVCAPIBinder.TMVCAPIBinderItem.HookBeforePost(DataSet: TDataSet);
var
lRes: IRESTResponse;
lRes: IMVCRESTResponse;
lLastID: Integer;
begin
if not fLoading then
@ -694,9 +695,9 @@ begin
else
begin
lLastID := fDataSet.FieldByName(fPrimaryKeyNAme).AsInteger;
lRes := fRESTClient.DataSetUpdate(fURI, DataSet, lLastID.ToString);
lRes := fRESTClient.DataSetUpdate(fURI, lLastID.ToString, DataSet);
end;
if not(lRes.ResponseCode in [200, 201]) then
if not(lRes.StatusCode in [200, 201]) then
begin
ShowError(lRes);
end
@ -717,19 +718,13 @@ begin
DataSet.Open;
end;
procedure TMVCAPIBinder.TMVCAPIBinderItem.ShowError(const AResponse: IRESTResponse);
procedure TMVCAPIBinder.TMVCAPIBinderItem.ShowError(const AResponse: IMVCRESTResponse);
begin
if AResponse.HasError then
if not AResponse.Success then
raise EMVCException.Create(
AResponse.Error.ExceptionMessage + sLineBreak +
AResponse.Error.ExceptionClassname)
AResponse.StatusCode.ToString + ': ' + AResponse.StatusText + sLineBreak + AResponse.Content)
else
raise EMVCException.Create(AResponse.BodyAsString);
// else
// MessageDlg(
// AResponse.ResponseCode.ToString + ': ' + AResponse.ResponseText + sLineBreak +
// AResponse.BodyAsString,
// mtError, [mbOK], 0);
raise EMVCException.Create(AResponse.Content);
end;
end.

View File

@ -34,7 +34,8 @@ interface
uses
System.NetEncoding,
System.SysUtils,
System.Classes;
System.Classes,
MVCFramework.Commons;
type
@ -73,6 +74,8 @@ type
TMVCRESTClientConsts = record
public const
DEFAULT_ACCEPT_ENCODING = 'gzip,deflate';
DEFAULT_ACCEPT = TMVCMediaType.APPLICATION_JSON + ', ' + TMVCMediaType.TEXT_PLAIN + ', ' + TMVCMediaType.TEXT_HTML;
DEFAULT_USER_AGENT = 'DelphiMVCFramework RESTClient/' + DMVCFRAMEWORK_VERSION;
DEFAULT_FILE_NAME = 'file';
AUTHORIZATION_HEADER = 'Authorization';
BASIC_AUTH_PREFIX = 'Basic ';
@ -91,7 +94,6 @@ implementation
uses
IdCompressorZLib,
System.ZLib,
MVCFramework.Commons,
System.Net.Mime;
{ TMVCRESTParam }

View File

@ -77,7 +77,12 @@ type
fHTTPClient: THTTPClient;
fBaseURL: string;
fResource: string;
fInternalContentType: string;
fAccept: string;
fAcceptCharset: string;
fAcceptEncoding: string;
fUserAgent: string;
fContentType: string;
fProxySettings: TProxySettings;
fParameters: TList<TMVCRESTParam>;
fRawBody: TStringStream;
@ -96,8 +101,8 @@ type
procedure DoConvertMVCPathParamsToRESTParams(var aURL: string);
procedure DoApplyPathParams(var aURL: string);
procedure DoApplyQueryParams(var aURL: string);
procedure DoApplyHeaders;
procedure DoApplyCookies(const aURL: string);
procedure DoApplyHeaders;
procedure DoEncodeURL(var aURL: string);
procedure DoPrepareBodyRequest(var aBodyStream: TStream);
@ -127,8 +132,6 @@ type
function SecureProtocols(const aSecureProtocols: THTTPSecureProtocols): IMVCRESTClient; overload;
function SecureProtocols: THTTPSecureProtocols; overload;
{$ENDIF}
function UserAgent(const aUserAgent: string): IMVCRESTClient; overload;
function UserAgent: string; overload;
/// <summary>
/// Clears all parameters (headers, body, path params and query params). This method is executed after each
@ -233,6 +236,8 @@ type
function HandleRedirects: Boolean; overload;
function MaxRedirects(const aMaxRedirects: Integer): IMVCRESTClient; overload;
function MaxRedirects: Integer; overload;
function UserAgent(const aUserAgent: string): IMVCRESTClient; overload;
function UserAgent: string; overload;
function Resource(const aResource: string): IMVCRESTClient; overload;
function Resource: string; overload;
@ -433,32 +438,35 @@ uses
function TMVCRESTClient.Accept: string;
begin
Result := HeaderValue(sAccept);
Result := fAccept;
end;
function TMVCRESTClient.Accept(const aAccept: string): IMVCRESTClient;
begin
Result := AddHeader(sAccept, aAccept);
Result := Self;
fAccept := aAccept;
end;
function TMVCRESTClient.AcceptCharset: string;
begin
Result := HeaderValue(sAcceptCharSet);
Result := fAcceptCharset;
end;
function TMVCRESTClient.AcceptCharset(const aAcceptCharset: string): IMVCRESTClient;
begin
Result := AddHeader(sAcceptCharset, aAcceptCharset);
Result := Self;
fAcceptCharset := aAcceptCharset;
end;
function TMVCRESTClient.AcceptEncoding(const aAcceptEncoding: string): IMVCRESTClient;
begin
Result := AddHeader(sAcceptEncoding, aAcceptEncoding);
Result := Self;
fAcceptEncoding := aAcceptEncoding;
end;
function TMVCRESTClient.AcceptEncoding: string;
begin
Result := HeaderValue(sAcceptEncoding);
Result := fAcceptEncoding;
end;
function TMVCRESTClient.AddBody(const aBody: string; const aContentType: string): IMVCRESTClient;
@ -701,7 +709,7 @@ begin
Result := Self;
ClearParameters(TMVCRESTParamType.FormURLEncoded);
fInternalContentType := '';
fContentType := '';
end;
function TMVCRESTClient.ClearCookies: IMVCRESTClient;
@ -756,6 +764,10 @@ begin
inherited Create;
fHTTPClient := THTTPClient.Create;
fHTTPClient.HandleRedirects := True;
fHTTPClient.MaxRedirects := CHTTPDefMaxRedirects;
fHTTPClient.SecureProtocols := CHTTPDefSecureProtocols;
fParameters := TList<TMVCRESTParam>.Create;
fRawBody := TStringStream.Create;
fBodyFormData := nil;
@ -765,6 +777,11 @@ begin
fBaseURL := '';
fResource := '';
fAccept := TMVCRESTClientConsts.DEFAULT_ACCEPT;
fAcceptCharset := '';
fAcceptEncoding := TMVCRESTClientConsts.DEFAULT_ACCEPT_ENCODING;
fUserAgent := TMVCRESTClientConsts.DEFAULT_USER_AGENT;
fContentType := '';
end;
function TMVCRESTClient.DataSetDelete(const aResource, aKeyValue: string): IMVCRESTResponse;
@ -845,6 +862,10 @@ begin
fHTTPClient.CustomHeaders[lParam.Name] := lParam.Value;
end;
end;
fHTTPClient.Accept := fAccept;
fHTTPClient.AcceptCharSet := fAcceptCharset;
fHTTPClient.AcceptEncoding := fAcceptEncoding;
fHTTPClient.ContentType := fContentType;
end;
procedure TMVCRESTClient.DoApplyPathParams(var aURL: string);
@ -914,13 +935,12 @@ var
lValue: string;
lBody: string;
begin
SplitContentMediaTypeAndCharset(fInternalContentType, lContentType, lContentCharset);
SplitContentMediaTypeAndCharset(fContentType, lContentType, lContentCharset);
if SameText(lContentType, TMVCMediaType.MULTIPART_FORM_DATA) then
begin
aBodyStream := GetBodyFormData.Stream;
SetContentType(GetBodyFormData.MimeTypeHeader);
fHTTPClient.CustHeaders[sContentType] := GetBodyFormData.MimeTypeHeader;
end
else if SameText(lContentType, TMVCMediaType.APPLICATION_FORM_URLENCODED) then
begin
@ -936,7 +956,7 @@ begin
lBody := lBody + lName + '=' + lValue;
end;
end;
AddBody(lBody, fInternalContentType);
AddBody(lBody, fContentType);
aBodyStream := fRawBody;
end
else
@ -959,11 +979,11 @@ begin
DoApplyPathParams(lURL);
DoApplyQueryParams(lURL);
DoEncodeURL(lURL);
DoApplyHeaders;
DoApplyCookies(lURL);
lBodyStream := nil;
DoPrepareBodyRequest(lBodyStream);
DoApplyHeaders;
case aMethod of
httpGET:
@ -1281,18 +1301,18 @@ end;
procedure TMVCRESTClient.SetContentType(const aContentType: string);
begin
fInternalContentType := aContentType;
AddHeader(sContentType, aContentType);
fContentType := aContentType;
end;
function TMVCRESTClient.UserAgent(const aUserAgent: string): IMVCRESTClient;
begin
Result := AddHeader(sUserAgent, aUserAgent);
Result := Self;
fUserAgent := aUserAgent;
end;
function TMVCRESTClient.UserAgent: string;
begin
Result := HeaderValue(sUserAgent);
Result := fUserAgent;
end;
{ TMVCRESTResponse }

View File

@ -677,7 +677,6 @@ begin
lRes := RESTClient.Accept('text/html').Post('/system/users/logged', TSystemJSON.JSONValueToString(lJSON, false));
SplitContentMediaTypeAndCharset(lRes.ContentType, lContentType, lContentCharset);
Assert.AreEqual(lContentType, TMVCMediaType.APPLICATION_JSON);
Assert.AreEqual(lContentCharset, TMVCCharSet.UTF_8);
Assert.areEqual<Integer>(HTTP_STATUS.OK, lRes.StatusCode);
Assert.areEqual('/system/users/logged', lRes.HeaderValue('X-LOGOUT-URL'));
Assert.areEqual('DELETE', lRes.HeaderValue('X-LOGOUT-METHOD'));
@ -705,7 +704,7 @@ begin
lJSON := System.JSON.TJSONObject.Create;
try
// no request body
lRes := RESTClient.Post('/system/users/logged');
lRes := RESTClient.AddBody('',TMVCMediaType.APPLICATION_JSON).Post('/system/users/logged');
Assert.areEqual<Integer>(HTTP_STATUS.BadRequest, lRes.StatusCode,
'Empty request body doesn''t return HTTP 400 Bad Request');
@ -779,9 +778,6 @@ var
lRes: IMVCRESTResponse;
lJSON: System.JSON.TJSONObject;
lLogoutUrl: string;
lValue: string;
I: Integer;
lPieces: TArray<string>;
lPass: Boolean;
lCookie: TCookie;
begin
@ -1049,13 +1045,13 @@ begin
lRes := RESTClient.Accept(TMVCMediaType.TEXT_HTML).Get('/static.html');
Assert.areEqual(404, lRes.StatusCode, '/static.html');
lRes := RESTClient.Accept(TMVCMediaType.TEXT_HTML).Get('/static');
lRes := RESTClient.HandleRedirects(False).Accept(TMVCMediaType.TEXT_HTML).Get('/static');
Assert.areEqual(301, lRes.StatusCode, '/static');
lRes := RESTClient.Accept(TMVCMediaType.TEXT_HTML).Get('/static/');
Assert.areEqual(200, lRes.StatusCode, '/static/');
lRes := RESTClient.Accept(TMVCMediaType.TEXT_HTML).Get('/static/folder1');
lRes := RESTClient.HandleRedirects(False).Accept(TMVCMediaType.TEXT_HTML).Get('/static/folder1');
Assert.areEqual(301, lRes.StatusCode, '/static/folder1');
lRes := RESTClient.Accept(TMVCMediaType.TEXT_HTML).Get('/static/folder1/');
@ -1622,7 +1618,7 @@ begin
lRes := RESTClient.Accept(TMVCMediaType.TEXT_HTML).Get('/static/');
Assert.areEqual(200, lRes.StatusCode, '/static/');
lRes := RESTClient.Accept(TMVCMediaType.TEXT_HTML).Get('/static');
lRes := RESTClient.HandleRedirects(False).Accept(TMVCMediaType.TEXT_HTML).Get('/static');
Assert.areEqual(301, lRes.StatusCode, '/static');
Assert.areEqual('/static/', lRes.HeaderValue('Location'), 'Wrong redirect');
end;
@ -1826,7 +1822,7 @@ begin
lUrl := '..\' + lUrl;
lRes := RESTClient.Accept(TMVCMediaType.TEXT_HTML).Get('/spa/' + lUrl);
Assert.areEqual(404, lRes.StatusCode);
Assert.Contains(lRes.Content, '404: [EMVCException] Not Found', true);
Assert.Contains(lRes.StatusText, '[EMVCException] Not Found', True);
end;
end;