-
Notifications
You must be signed in to change notification settings - Fork 349
Expand file tree
/
Copy pathDbExceptionParserUnitTests.cs
More file actions
142 lines (133 loc) · 7 KB
/
Copy pathDbExceptionParserUnitTests.cs
File metadata and controls
142 lines (133 loc) · 7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.IO.Abstractions.TestingHelpers;
using Azure.DataApiBuilder.Config;
using Azure.DataApiBuilder.Config.ObjectModel;
using Azure.DataApiBuilder.Core.Configurations;
using Azure.DataApiBuilder.Core.Resolvers;
using Azure.DataApiBuilder.Service.Exceptions;
using Azure.DataApiBuilder.Service.Tests.SqlTests;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
namespace Azure.DataApiBuilder.Service.Tests.UnitTests
{
/// <summary>
/// Unit Test class for DbExceptionParserBase
/// </summary>
[TestClass]
public class DbExceptionParserUnitTests
{
/// <summary>
/// Verify that the DbExceptionParser returns the correct
/// messaging based on the mode provided as argument.
/// </summary>
/// <param name="isDeveloperMode">true for developer mode, false otherwise.</param>
/// <param name="expected">Expected error message.</param>
[DataTestMethod]
[DataRow(true, "Development Mode Error Message.")]
[DataRow(false, "While processing your request the database ran into an error.")]
public void VerifyCorrectErrorMessage(bool isDeveloperMode, string expected)
{
RuntimeConfig mockConfig = new(
Schema: "",
DataSource: new(DatabaseType.MSSQL, "", new()),
Runtime: new(
Rest: new(),
GraphQL: new(),
Mcp: new(),
Host: new(null, null, isDeveloperMode ? HostMode.Development : HostMode.Production)
),
Entities: new(new Dictionary<string, Entity>())
);
// We can use any other error code here, doesn't really matter.
int connectionEstablishmentError = 53;
MockFileSystem fileSystem = new();
fileSystem.AddFile(FileSystemRuntimeConfigLoader.DEFAULT_CONFIG_FILE_NAME, new MockFileData(mockConfig.ToJson()));
FileSystemRuntimeConfigLoader loader = new(fileSystem);
RuntimeConfigProvider provider = new(loader);
// Invoke base class implementation if no expectation overrides the member
// (a.k.a. "Partial Mocks" in Rhino Mocks): default is false.
// Without setting CallBase = true, the base class implementation of GetMessage(e) will
// not be invoked and will return null.
// https://github.com/devlooped/moq/wiki/Quickstart#customizing-mock-behavior
Mock<DbExceptionParser> parser = new(provider) { CallBase = true };
DbException e = SqlTestHelper.CreateSqlException(connectionEstablishmentError, expected);
Exception parsedException = parser.Object.Parse(e);
Assert.AreEqual(expected: expected, actual: parsedException.Message);
}
/// <summary>
/// Method to validate usage of the MsSqlDbExceptionParser.IsTransientException method.
/// </summary>
/// <param name="expected">boolean value indicating if exception is expected to be transient or not.</param>
/// <param name="number">number to be populated in SqlException.Number field</param>
[DataTestMethod]
[DataRow(true, 121, DisplayName = "Transient exception error code #1")]
[DataRow(true, 8628, DisplayName = "Transient exception error code #2")]
[DataRow(true, 926, DisplayName = "Transient exception error code #3")]
[DataRow(false, 107, DisplayName = "Non-transient exception error code #1")]
[DataRow(false, 209, DisplayName = "Non-transient exception error code #2")]
public void TestIsTransientExceptionMethod(bool expected, int number)
{
RuntimeConfig mockConfig = new(
Schema: "",
DataSource: new(DatabaseType.MSSQL, "", new()),
Runtime: new(
Rest: new(),
GraphQL: new(),
Mcp: new(),
Host: new(null, null, HostMode.Development)
),
Entities: new(new Dictionary<string, Entity>())
);
MockFileSystem fileSystem = new();
fileSystem.AddFile(FileSystemRuntimeConfigLoader.DEFAULT_CONFIG_FILE_NAME, new MockFileData(mockConfig.ToJson()));
FileSystemRuntimeConfigLoader loader = new(fileSystem);
RuntimeConfigProvider provider = new(loader);
DbExceptionParser dbExceptionParser = new MsSqlDbExceptionParser(provider);
Assert.AreEqual(expected, dbExceptionParser.IsTransientException(SqlTestHelper.CreateSqlException(number)));
}
/// <summary>
/// Validates that JSON data type validation error codes raised by SQL Server 2025+
/// when invalid JSON is supplied for a json column are mapped to HTTP 400 Bad Request
/// and are classified as client input errors.
/// </summary>
/// <param name="number">SQL error code populated in SqlException.Number.</param>
[DataTestMethod]
[DataRow(13608, DisplayName = "JSON validation error code 13608 maps to 400")]
[DataRow(13609, DisplayName = "JSON validation error code 13609 maps to 400")]
[DataRow(13610, DisplayName = "JSON validation error code 13610 maps to 400")]
[DataRow(13611, DisplayName = "JSON validation error code 13611 maps to 400")]
[DataRow(13612, DisplayName = "JSON validation error code 13612 maps to 400")]
[DataRow(13613, DisplayName = "JSON validation error code 13613 maps to 400")]
[DataRow(13614, DisplayName = "JSON validation error code 13614 maps to 400")]
public void TestJsonValidationErrorsMapToBadRequest(int number)
{
RuntimeConfig mockConfig = new(
Schema: "",
DataSource: new(DatabaseType.MSSQL, "", new()),
Runtime: new(
Rest: new(),
GraphQL: new(),
Mcp: new(),
Host: new(null, null, HostMode.Development)
),
Entities: new(new Dictionary<string, Entity>())
);
MockFileSystem fileSystem = new();
fileSystem.AddFile(FileSystemRuntimeConfigLoader.DEFAULT_CONFIG_FILE_NAME, new MockFileData(mockConfig.ToJson()));
FileSystemRuntimeConfigLoader loader = new(fileSystem);
RuntimeConfigProvider provider = new(loader);
DbExceptionParser dbExceptionParser = new MsSqlDbExceptionParser(provider);
DbException sqlException = SqlTestHelper.CreateSqlException(number);
Assert.AreEqual(
System.Net.HttpStatusCode.BadRequest,
dbExceptionParser.GetHttpStatusCodeForException(sqlException));
Assert.AreEqual(
DataApiBuilderException.SubStatusCodes.DatabaseInputError,
dbExceptionParser.GetResultSubStatusCodeForException(sqlException));
}
}
}