mirror of
https://github.com/danieleteti/delphimvcframework.git
synced 2024-11-15 15:55:54 +01:00
RESTClient improvements and LiveTest adjustments
This commit is contained in:
parent
ff5aefbd15
commit
b21096b515
@ -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.
|
||||
|
@ -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 }
|
||||
|
@ -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 }
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user