/// <summary> /// Initializes a new instance of the ErrorResponseVerifier class /// </summary> /// <param name="expectedErrorMessage">Expected error message to compare against</param> /// <param name="resourceVerifier">resource verifier for to use for the error message. Can be null if the expected errors provide specific verifiers.</param> public ErrorResponseVerifier(ExpectedErrorMessage expectedErrorMessage, IStringResourceVerifier resourceVerifier) : base() { ExceptionUtilities.CheckArgumentNotNull(expectedErrorMessage, "expectedErrorMessage"); this.ExpectedErrorMessage = expectedErrorMessage; this.ResourceVerifier = resourceVerifier; }
/// <summary> /// Initializes a new instance of the ExpectedException class. /// </summary> /// <param name="exceptionType">The Type of exception expected.</param> /// <param name="errorMessage">The expected error message</param> /// <param name="exactMessageMatch">Whether or not to match the resource string exactly. Default is true.</param> public ExpectedException(Type exceptionType, ExpectedErrorMessage errorMessage, bool exactMessageMatch = true) { ExceptionUtilities.CheckArgumentNotNull(exceptionType, "exceptionType"); ExceptionUtilities.CheckArgumentNotNull(errorMessage, "errorMessage"); ExceptionUtilities.Assert(typeof(Exception).IsAssignableFrom(exceptionType), "The type passed as exceptionType must be an exception type"); this.ExpectedExceptionType = exceptionType; this.ExpectedMessage = errorMessage; this.ExactMatch = exactMessageMatch; }
/// <summary> /// Verifies that the error matches /// </summary> /// <param name="expected">The expected error message</param> /// <param name="defaultVerifier">The verifier to use if the message does not have one set</param> /// <param name="actual">The actual error string</param> /// <param name="isExactMatch">Whether to perform an exact match</param> public static void VerifyMatch(this ExpectedErrorMessage expected, IStringResourceVerifier defaultVerifier, string actual, bool isExactMatch) { ExceptionUtilities.CheckArgumentNotNull(expected, "expected"); var verifier = expected.Verifier ?? defaultVerifier; ExceptionUtilities.CheckObjectNotNull(verifier, "Either a default verifier or specific message verifier must be provided"); verifier.VerifyMatch(expected.ResourceIdentifier, actual, isExactMatch, expected.Arguments.ToArray()); }
/// <summary> /// Wraps the current error with the specified parent error and returns the parent error. /// </summary> /// <param name="parentErrorMessage">The parent error to wrap this error in.</param> /// <returns>The parent error</returns> public ExpectedErrorMessage AddParent(ExpectedErrorMessage parentErrorMessage) { parentErrorMessage.InnerError = this; if (parentErrorMessage.Verifier == null) { parentErrorMessage.Verifier = this.Verifier; } return(parentErrorMessage); }
internal static CodeExpression BuildExpectedErrorMessage(ExpectedErrorMessage expectedErrorMessage) { List<CodeExpression> codeExpressions = new List<CodeExpression>(); codeExpressions.Add(Code.Primitive(expectedErrorMessage.ResourceIdentifier)); codeExpressions.AddRange(expectedErrorMessage.Arguments.ToArray().Select(r => Code.Primitive(r))); CodeExpression codeExpression = Code.New(Code.TypeRef(typeof(ExpectedErrorMessage)), codeExpressions.ToArray()); if (expectedErrorMessage.InnerError != null) { codeExpression = BuildExpectedErrorMessage(expectedErrorMessage.InnerError).Call("AddParent", codeExpression); } return codeExpression; }
/// <summary> /// Verifies the ExceptionMessage recursively /// </summary> /// <param name="expectedErrorMessage">Error Message to Verify</param> /// <param name="resourceVerifier">Resource Verifier to use</param> /// <param name="errorPayload">Error payload to verify</param> /// <param name="assert">assert call to make</param> public static void VerifyExceptionMessage(this ExpectedErrorMessage expectedErrorMessage, IStringResourceVerifier resourceVerifier, ODataErrorPayload errorPayload, Action <bool, string> assert) { ExceptionUtilities.CheckArgumentNotNull(expectedErrorMessage, "expectedErrorMessage"); ExceptionUtilities.CheckArgumentNotNull(resourceVerifier, "resourceVerifier"); ExceptionUtilities.CheckArgumentNotNull(errorPayload, "errorPayload"); ExceptionUtilities.CheckArgumentNotNull(assert, "assert"); // Verify messages are the same // TODO: Need to also verify the language and code expectedErrorMessage.VerifyMatch(resourceVerifier, errorPayload.Message, true); ExpectedErrorMessage expectedInnerError = expectedErrorMessage.InnerError; ODataInternalExceptionPayload innerError = errorPayload.InnerError; // Set it to null so comparison won't occur if (expectedErrorMessage.SkipInnerErrorVerification) { innerError = null; expectedInnerError = null; } while (innerError != null) { // TODO: better error message assert(expectedInnerError != null, "Did not expect inner error"); // Verify messages are the same expectedInnerError.VerifyMatch(resourceVerifier, innerError.Message, true); if (expectedInnerError.SkipInnerErrorVerification) { innerError = null; expectedInnerError = null; } else { // TODO: verify stack trace, type name, etc innerError = innerError.InternalException; expectedInnerError = expectedInnerError.InnerError; } } }
internal static HttpStatusCode GetExpectedErrorStatusCode(ExpectedErrorMessage errorInformation) { if (errorInformation.ResourceIdentifier == "DataServiceException_GeneralError" || errorInformation.ResourceIdentifier == "DataServiceConfiguration_ResponseVersionIsBiggerThanProtocolVersion") { return HttpStatusCode.InternalServerError; } return HttpStatusCode.BadRequest; }
private IResponseVerifier BuildErrorResponseVerifier(ExpectedErrorMessage expectedMessage, IStringResourceVerifier resourceVerifier) { return new ErrorResponseVerifier(expectedMessage, resourceVerifier); }
/// <summary> /// Returns a composite verifier with all standard verifiers attached /// </summary> /// <param name="expectedStatusCode">The expected status code of the response</param> /// <param name="expectedMessage">The expected error message</param> /// <param name="resourceVerifier">The resource verifier for the error message</param> /// <returns>A composite verifier</returns> public IResponseVerifier GetErrorVerifier(HttpStatusCode expectedStatusCode, ExpectedErrorMessage expectedMessage, IStringResourceVerifier resourceVerifier) { ExceptionUtilities.CheckArgumentNotNull(expectedMessage, "expectedMessage"); ExceptionUtilities.CheckArgumentNotNull(resourceVerifier, "resourceVerifier"); ExceptionUtilities.CheckObjectNotNull(this.BuildErrorVerifierFunc, "Delegate for building standard verifier cannot be null"); ExceptionUtilities.CheckAllRequiredDependencies(this); var verifier = this.BuildErrorVerifierFunc(expectedStatusCode, expectedMessage, resourceVerifier); this.Injector.InjectDependenciesInto(verifier); verifier.Verifiers.ForEach(v => this.Injector.InjectDependenciesInto(v)); return verifier; }
/// <summary> /// Wraps the current error with the specified parent error and returns the parent error. /// </summary> /// <param name="parentErrorMessage">The parent error to wrap this error in.</param> /// <returns>The parent error</returns> public ExpectedErrorMessage AddParent(ExpectedErrorMessage parentErrorMessage) { parentErrorMessage.InnerError = this; if (parentErrorMessage.Verifier == null) { parentErrorMessage.Verifier = this.Verifier; } return parentErrorMessage; }
/// <summary> /// Returns the error expected for the Query /// </summary> /// <param name="expression">The expression.</param> /// <param name="usesClientQueryable">Whether the client uri is build from a Client Linq expression or not</param> /// <param name="clientMaxProtocolVersion">Client Max Protocol Version</param> /// <param name="maxProtocolVersion">Max Protocol version of the server</param> /// <returns> a versioning error at the Client level</returns> public ExpectedClientErrorBaseline CalculateExpectedClientVersionError(QueryExpression expression, bool usesClientQueryable, DataServiceProtocolVersion clientMaxProtocolVersion, DataServiceProtocolVersion maxProtocolVersion) { ExceptionUtilities.CheckArgumentNotNull(expression, "expression"); ExceptionUtilities.CheckAllRequiredDependencies(this); DataServiceProtocolVersion expectedDataServiceVersion = DataServiceProtocolVersion.Unspecified; DataServiceProtocolVersion minRequiredRequestVersion = DataServiceProtocolVersion.Unspecified; ExpectedErrorMessage errorInformation; // If the Client Queryable interface is not used to build the expression that is run then no error can happen at this stage // There can only be a protocol error from the server if there is no client error var serverExpression = this.ClientSideProjectionReplacer.ReplaceClientSideProjections(expression); ODataUri odataUri = this.QueryToODataUriConverter.ComputeUri(serverExpression); // Predict what the Client will generate for the data service version, if we are not using client.linq its unspecified otherwise calculate it if (usesClientQueryable) { ExpectedClientErrorBaseline expectedErrorIfTooLow; minRequiredRequestVersion = this.CalculateExpectedClientMinRequestVersion(odataUri, out expectedErrorIfTooLow); if (minRequiredRequestVersion > clientMaxProtocolVersion) { if (expectedErrorIfTooLow == null) { errorInformation = new ExpectedErrorMessage("Context_RequestVersionIsBiggerThanProtocolVersion", minRequiredRequestVersion.ConvertToHeaderFormat(), clientMaxProtocolVersion.ConvertToHeaderFormat()); expectedErrorIfTooLow = new ExpectedClientErrorBaseline(typeof(InvalidOperationException), false, errorInformation); } return expectedErrorIfTooLow; } EntitySet expectedEntitySet = null; if (odataUri.TryGetExpectedEntitySet(out expectedEntitySet)) { DataServiceProtocolVersion entitySetVersion = expectedEntitySet.CalculateEntitySetProtocolVersion(MimeTypes.ApplicationAtomXml, VersionCalculationType.Request, maxProtocolVersion, clientMaxProtocolVersion); // Client will create a DSV based on the following pieces, metadata of the query based on sets it goes through, uri contructs (select, count, inlinecount, etc) // and headers (like DataServiceResponsePreference). In order to mimic this client behavior I will get the metadata version and a version // from the minrequestVersion and take the max. MinRequest deals with Uri and headers, metadata the metadata. expectedDataServiceVersion = VersionHelper.GetMaximumVersion(minRequiredRequestVersion, entitySetVersion); } } ODataRequest request = new ODataRequest(this.ODataUriToStringConverter) { Uri = odataUri, Verb = HttpVerb.Get, Headers = { { HttpHeaders.DataServiceVersion, expectedDataServiceVersion.ConvertToHeaderFormat() }, { HttpHeaders.MaxDataServiceVersion, clientMaxProtocolVersion.ConvertToHeaderFormat() }, { HttpHeaders.Accept, MimeTypes.ApplicationAtomXml } } }; if (this.ODataRequestVersionResourceErrorCalculator.TryCalculateError(request, maxProtocolVersion, out errorInformation)) { return new ExpectedClientErrorBaseline(typeof(DSClient.DataServiceQueryException), true, errorInformation); } return null; }
private DataServiceProtocolVersion CalculateExpectedClientMinRequestVersion(ODataUri odataUri, out ExpectedClientErrorBaseline errorIfTooLow) { ExceptionUtilities.CheckArgumentNotNull(odataUri, "odataUri"); DataServiceProtocolVersion expectedVersion = DataServiceProtocolVersion.V4; errorIfTooLow = null; // Uri specific processing if (odataUri.HasAnyOrAllInFilter()) { expectedVersion = VersionHelper.IncreaseVersionIfRequired(expectedVersion, DataServiceProtocolVersion.V4); string anyOrAll = string.Empty; if (odataUri.Filter.Contains("/any(")) { anyOrAll = "Any"; } else { anyOrAll = "All"; } var errorInformation = new ExpectedErrorMessage("ALinq_MethodNotSupportedForMaxDataServiceVersionLessThanX", anyOrAll, expectedVersion.ConvertToHeaderFormat()); errorIfTooLow = new ExpectedClientErrorBaseline(typeof(NotSupportedException), false, errorInformation); } if (odataUri.HasSignificantTypeSegmentInPath()) { // TODO: this seems like it should be inferred from the query, not the uri expectedVersion = VersionHelper.IncreaseVersionIfRequired(expectedVersion, DataServiceProtocolVersion.V4); var errorInformation = new ExpectedErrorMessage("ALinq_MethodNotSupportedForMaxDataServiceVersionLessThanX", "OfType", expectedVersion.ConvertToHeaderFormat()); errorIfTooLow = new ExpectedClientErrorBaseline(typeof(NotSupportedException), false, errorInformation); } else if (odataUri.HasTypeSegmentInExpandOrSelect()) { // TODO: this seems like it should be inferred from the query, not the uri expectedVersion = VersionHelper.IncreaseVersionIfRequired(expectedVersion, DataServiceProtocolVersion.V4); var errorInformation = new ExpectedErrorMessage("ALinq_TypeAsNotSupportedForMaxDataServiceVersionLessThan3"); errorIfTooLow = new ExpectedClientErrorBaseline(typeof(NotSupportedException), false, errorInformation); } return expectedVersion; }