Skip to content

Commit cf01fe2

Browse files
committed
ShouldExportRecordAsync => FAIL
1 parent 87dd51f commit cf01fe2

15 files changed

+1108
-852
lines changed

RedcapApi/Broker/ApiBroker.cs

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
using System;
2+
using System.Net.Http;
3+
using System.Runtime.CompilerServices;
4+
using System.Threading;
5+
using System.Threading.Tasks;
6+
7+
using RestSharp;
8+
9+
using Serilog;
10+
11+
namespace Redcap.Broker
12+
{
13+
public partial class ApiBroker: IApiBroker
14+
{
15+
protected readonly HttpClient httpClient;
16+
protected readonly IRestClient restClient;
17+
public ApiBroker(HttpClient httpClient, IRestClient restClient)
18+
{
19+
this.httpClient = httpClient;
20+
this.restClient = restClient;
21+
}
22+
public void LogException(Exception ex,
23+
[CallerMemberName] string method = null,
24+
[CallerFilePath] string filePath = null,
25+
[CallerLineNumber] int lineNumber = 0)
26+
{
27+
var errorMessage = $"Message: {ex.Message}. Method: {method} File: {filePath} LineNumber: {lineNumber}";
28+
Log.Error($"Message: {ex.Message}. Method: {method} File: {filePath} LineNumber: {lineNumber}");
29+
throw new Exception(errorMessage);
30+
}
31+
public async Task<T> PostAsync<T>(IRestRequest request, CancellationToken cancellationToken = default)
32+
{
33+
var response = await restClient.PostAsync<T>(request, cancellationToken);
34+
35+
return response;
36+
}
37+
public async Task<T> ExecuteAsync<T>(RestRequest request) where T : new()
38+
{
39+
var response = await restClient.ExecuteAsync<T>(request);
40+
if(response.ErrorException != null)
41+
{
42+
LogException(response.ErrorException);
43+
}
44+
return response.Data;
45+
}
46+
}
47+
}

RedcapApi/Broker/IApiBroker.cs

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using System;
2+
using System.Runtime.CompilerServices;
3+
using System.Threading;
4+
using System.Threading.Tasks;
5+
6+
using RestSharp;
7+
8+
namespace Redcap.Broker
9+
{
10+
public interface IApiBroker
11+
{
12+
Task<T> ExecuteAsync<T>(RestRequest request) where T : new();
13+
void LogException(Exception ex, [CallerMemberName] string method = null, [CallerFilePath] string filePath = null, [CallerLineNumber] int lineNumber = 0);
14+
Task<T> PostAsync<T>(IRestRequest request, CancellationToken cancellationToken = default);
15+
}
16+
}

RedcapApi/Models/Demographic.cs

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
using Newtonsoft.Json;
2+
3+
namespace Redcap.Models
4+
{
5+
/// <summary>
6+
/// Simplified demographics instrument that we can test with.
7+
/// </summary>
8+
public class Demographic
9+
{
10+
/// <summary>
11+
///
12+
/// </summary>
13+
[JsonRequired]
14+
[JsonProperty("record_id")]
15+
public string RecordId { get; set; }
16+
17+
/// <summary>
18+
///
19+
/// </summary>
20+
[JsonProperty("first_name")]
21+
public string FirstName { get; set; }
22+
23+
/// <summary>
24+
///
25+
/// </summary>
26+
[JsonProperty("last_name")]
27+
public string LastName { get; set; }
28+
}
29+
}

RedcapApi/Redcap.csproj

+10-8
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<Project Sdk="Microsoft.NET.Sdk">
33
<PropertyGroup>
4-
<TargetFramework>netstandard2.0</TargetFramework>
4+
<TargetFramework>netstandard2.1</TargetFramework>
55
<Authors>Michael Tran</Authors>
66
<Company>Virginia Commonwealth University</Company>
77
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
@@ -28,7 +28,7 @@
2828
<Copyright>https://github.com/cctrbic/redcap-api/blob/master/LICENSE.md</Copyright>
2929
<icon>https://vortex.cctr.vcu.edu/images/ram_crest_160.png</icon>
3030
<PackageLicenseExpression>MIT</PackageLicenseExpression>
31-
<PackageIcon>ram_crest_160.png</PackageIcon>
31+
<PackageIcon>vcu.png</PackageIcon>
3232
</PropertyGroup>
3333
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
3434
<Optimize>false</Optimize>
@@ -38,23 +38,25 @@
3838
<PlatformTarget>AnyCPU</PlatformTarget>
3939
</PropertyGroup>
4040
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
41-
<DocumentationFile>D:\Github\redcap-api\RedcapApi\Redcap.xml</DocumentationFile>
41+
<DocumentationFile></DocumentationFile>
4242
</PropertyGroup>
4343
<ItemGroup>
4444
<Compile Remove="bin\**" />
4545
<EmbeddedResource Remove="bin\**" />
4646
<None Remove="bin\**" />
47-
<None Include="..\ram_crest_160.png">
47+
<None Include="..\vcu.png">
4848
<Pack>True</Pack>
4949
<PackagePath></PackagePath>
5050
</None>
5151
</ItemGroup>
5252
<ItemGroup>
53-
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
54-
<PackageReference Include="Serilog" Version="2.7.1" />
55-
<PackageReference Include="System.ComponentModel.Annotations" Version="4.5.0" />
53+
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
54+
<PackageReference Include="RestSharp" Version="106.11.7" />
55+
<PackageReference Include="Serilog" Version="2.10.0" />
56+
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
57+
<PackageReference Include="System.Text.Json" Version="5.0.1" />
5658
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
57-
<PackageReference Include="xunit.extensibility.core" Version="2.4.0" />
59+
<PackageReference Include="xunit.extensibility.core" Version="2.4.1" />
5860
<Content Include="Models\RedcapMetaData.cs" />
5961
<Content Include="Models\RecordStatus.cs" />
6062
</ItemGroup>

RedcapApi/Redcap.xml

+20
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

RedcapApi/Services/ApiService.cs

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using System;
2+
using System.Threading.Tasks;
3+
4+
using Redcap.Broker;
5+
6+
namespace Redcap.Services
7+
{
8+
public class ApiService : IApiService
9+
{
10+
private readonly IApiBroker apiBroker;
11+
public ApiService(IApiBroker apiBroker)
12+
{
13+
this.apiBroker = apiBroker;
14+
}
15+
/// <summary>
16+
/// Exports a single record from REDCap.
17+
/// </summary>
18+
/// <typeparam name="T"></typeparam>
19+
/// <returns></returns>
20+
public async Task<T> ExportRecordAsync<T>()
21+
{
22+
throw new NotImplementedException();
23+
}
24+
}
25+
}

RedcapApi/Services/IApiService.cs

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
using System.Threading.Tasks;
2+
3+
namespace Redcap.Services
4+
{
5+
public interface IApiService
6+
{
7+
Task<T> ExportRecordAsync<T>();
8+
}
9+
}

RedcapApiDemo/RedcapApiDemo.csproj

+4-4
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22

33
<PropertyGroup>
44
<OutputType>Exe</OutputType>
5-
<TargetFramework>netcoreapp2.0</TargetFramework>
5+
<TargetFramework>net5.0</TargetFramework>
66
</PropertyGroup>
77

88
<ItemGroup>
9-
<PackageReference Include="CsvHelper" Version="7.1.1" />
10-
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
11-
<PackageReference Include="Serilog" Version="2.7.1" />
9+
<PackageReference Include="CsvHelper" Version="22.1.1" />
10+
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
11+
<PackageReference Include="Serilog" Version="2.10.0" />
1212
</ItemGroup>
1313

1414
<ItemGroup>
+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*
2+
* REDCap API Library
3+
4+
* Biomedical Informatics Core
5+
* C. Kenneth and Dianne Wright Center for Clinical and Translational Research
6+
* Virginia Commonwealth University
7+
*
8+
* Copyright (c) 2021 Virginia Commonwealth University
9+
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
10+
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
12+
*
13+
*/
14+
15+
using Redcap;
16+
using Redcap.Interfaces;
17+
18+
namespace Tests
19+
{
20+
public partial class RedcapApiTests
21+
{
22+
}
23+
}

Tests/RedcapApiTests.Records.cs

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
7+
using FluentAssertions;
8+
9+
using Moq;
10+
11+
using Redcap.Broker;
12+
using Redcap.Models;
13+
using Redcap.Services;
14+
15+
using RestSharp;
16+
17+
using Xunit;
18+
19+
namespace Tests
20+
{
21+
public partial class RedcapApiTests
22+
{
23+
[Fact]
24+
public async Task ShouldExportRecordAsync()
25+
{
26+
// arrange
27+
Demographic demographicInstrument = CreateDemographicsInstrument();
28+
Demographic inputDemographicInstrument = demographicInstrument;
29+
Demographic retrievedDemographicInstrument = inputDemographicInstrument;
30+
Demographic expectedDemographicInstrument = retrievedDemographicInstrument;
31+
var request = new RestRequest(apiUri, Method.POST);
32+
apiBrokerMock.Setup(broker => broker.ExecuteAsync<Demographic>(request))
33+
.ReturnsAsync(retrievedDemographicInstrument);
34+
// act
35+
Demographic actualDemographicInstrument = await apiService.ExportRecordAsync<Demographic>();
36+
37+
// assert
38+
actualDemographicInstrument.Should().BeEquivalentTo(expectedDemographicInstrument);
39+
}
40+
}
41+
}

0 commit comments

Comments
 (0)