Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .config/dotnet-tools.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"version": 1,
"isRoot": true,
"tools": {
"dotnet-reportgenerator-globaltool": {
"version": "5.5.10",
"commands": [
"reportgenerator"
],
"rollForward": false
}
}
}
24 changes: 23 additions & 1 deletion .github/workflows/dotnet.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,26 @@ jobs:
- name: Lint
run: ./scripts/lint.sh
- name: Test
run: dotnet test --no-build --verbosity normal
run: dotnet test --no-build --coverage --coverage-output-format cobertura --coverage-output coverage.cobertura.xml --verbosity normal
- name: Generate coverage report
run: dotnet reportgenerator "-reports:**/TestResults/coverage.cobertura.xml" "-targetdir:coverage-report" "-reporttypes:Html;Badges;TextSummary"
- name: Upload Pages artifact
if: github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/master'
uses: actions/upload-pages-artifact@v3
with:
path: ./coverage-report

deploy:
needs: build
if: github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/master'
runs-on: ubuntu-latest
permissions:
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ bld/
[Oo]bj/
[Ll]og/

# Test / coverage outputs
[Tt]est[Rr]esults/
coverage-report/
*.cobertura.xml
*.coverage

# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
Expand Down
8 changes: 4 additions & 4 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@
</ItemGroup>

<ItemGroup Label="Test">
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="18.5.1" />
<PackageVersion Include="xunit" Version="2.9.3" />
<PackageVersion Include="xunit.runner.visualstudio" Version="3.1.5" />
<PackageVersion Include="coverlet.collector" Version="10.0.0" />
<PackageVersion Include="TUnit" Version="1.44.0" />
<PackageVersion Include="Microsoft.Testing.Extensions.CodeCoverage" Version="18.6.2" />
<PackageVersion Include="RichardSzalay.MockHttp" Version="7.0.0" />
<PackageVersion Include="NSubstitute" Version="5.3.0" />
</ItemGroup>

</Project>
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

[![Nuget](https://img.shields.io/nuget/v/SharpChatwork.svg?style=flat-square)](https://www.nuget.org/packages/SharpChatwork/)

|Branch|Status|
|------|------|
|master|[![master](https://github.com/Egliss/SharpChatwork/actions/workflows/dotnet.yaml/badge.svg?branch=master)](https://github.com/Egliss/SharpChatwork/actions/workflows/dotnet.yaml)|
|develop|[![develop](https://github.com/Egliss/SharpChatwork/actions/workflows/dotnet.yaml/badge.svg?branch=develop)](https://github.com/Egliss/SharpChatwork/actions/workflows/dotnet.yaml)|
|Branch|Status|Coverage|
|------|------|--------|
|master|[![master](https://github.com/Egliss/SharpChatwork/actions/workflows/dotnet.yaml/badge.svg?branch=master)](https://github.com/Egliss/SharpChatwork/actions/workflows/dotnet.yaml)|[![coverage](https://egliss.github.io/SharpChatwork/badge_linecoverage.svg)](https://egliss.github.io/SharpChatwork/)|
|develop|[![develop](https://github.com/Egliss/SharpChatwork/actions/workflows/dotnet.yaml/badge.svg?branch=develop)](https://github.com/Egliss/SharpChatwork/actions/workflows/dotnet.yaml)|[![coverage](https://egliss.github.io/SharpChatwork/badge_linecoverage.svg)](https://egliss.github.io/SharpChatwork/)|

## API Support Status

Expand Down
16 changes: 6 additions & 10 deletions SharpChatwork.Test/SharpChatwork.Test.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,17 @@
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

<OutputType>Exe</OutputType>
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
<NoWarn>$(NoWarn);CA1707;CA2012</NoWarn>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" />
<PackageReference Include="xunit" />
<PackageReference Include="xunit.runner.visualstudio">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="TUnit" />
<PackageReference Include="Microsoft.Testing.Extensions.CodeCoverage" />
<PackageReference Include="RichardSzalay.MockHttp" />
<PackageReference Include="NSubstitute" />
</ItemGroup>

<ItemGroup>
Expand Down
65 changes: 65 additions & 0 deletions SharpChatwork.Test/src/Client/AccessTokenClientTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
using System.Text.Json;
using SharpChatwork.Client.Exceptions;
using SharpChatwork.Test.Helpers;

namespace SharpChatwork.Test.Client;

public class AccessTokenClientTests
{
[Test]
public async Task QueryAsync_sends_x_chatworktoken_header_and_deserializes_response()
{
var (client, handler) = MockedAccessTokenClient.Create("my-token");
handler.Expect(HttpMethod.Get, EndPoints.Me.ToString())
.WithHeaders("X-ChatWorkToken", "my-token")
.Respond("application/json", ApiFixtures.MeGet);

var user = await client.me.GetUserAsync();

await Assert.That(user.account_id).IsEqualTo(123);
await Assert.That(user.name).IsEqualTo("John Smith");
handler.VerifyNoOutstandingExpectation();
}

[Test]
public async Task QueryAsync_throws_ChatworkClientException_on_non_success_status()
{
var (client, handler) = MockedAccessTokenClient.Create();
handler.When(EndPoints.Me.ToString())
.Respond(HttpStatusCode.InternalServerError, "application/json", ApiFixtures.ErrorResponse);

await Assert.That(async () => await client.me.GetUserAsync())
.ThrowsExactly<ChatworkClientException>();
}

[Test]
public async Task QueryAsync_throws_JsonException_on_malformed_response()
{
var (client, handler) = MockedAccessTokenClient.Create();
handler.When(EndPoints.Me.ToString())
.Respond("application/json", "{not-json");

await Assert.That(async () => await client.me.GetUserAsync())
.Throws<JsonException>();
}

[Test]
public async Task QueryAsync_uses_specified_http_method_for_post_request()
{
var (client, handler) = MockedAccessTokenClient.Create();
handler.Expect(HttpMethod.Post, EndPoints.RoomMessages(42).ToString())
.Respond("application/json", ApiFixtures.MessageIdResult);

var result = await client.room.message.SendAsync(42, "hi", isSelfUnread: false);

await Assert.That(result.message_id).IsEqualTo("9876");
handler.VerifyNoOutstandingExpectation();
}

[Test]
public async Task ClientName_returns_class_name()
{
var (client, _) = MockedAccessTokenClient.Create();
await Assert.That(client.clientName).IsEqualTo(nameof(AccessToken.AccessTokenClient));
}
}
51 changes: 51 additions & 0 deletions SharpChatwork.Test/src/Client/OAuth2ClientTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
using System.Text;
using SharpChatwork.OAuth2;
using SharpChatwork.Test.Helpers;

namespace SharpChatwork.Test.Client;

public class OAuth2ClientTests
{
[Test]
public async Task UpdateTokenAsync_uses_basic_auth_with_client_and_secret()
{
var (client, handler) = MockedOAuth2Client.Create("ck", "sk");
var expected = "Basic " + Convert.ToBase64String(Encoding.ASCII.GetBytes("ck:sk"));
handler.Expect(HttpMethod.Post, EndPoints.Token.ToString())
.WithHeaders("Authorization", expected)
.Respond("application/json", ApiFixtures.OAuth2TokenResult);

var result = await client.UpdateTokenAsync(OAuth2TokenQuery.GrantType.RefreshToken);

await Assert.That(result.access_token).IsEqualTo("abc-access");
await Assert.That(result.refresh_token).IsEqualTo("abc-refresh");
await Assert.That(result.expires_in).IsEqualTo(3600L);
await Assert.That(result.isError).IsFalse();
handler.VerifyNoOutstandingExpectation();
}

[Test]
public async Task QueryAsync_sends_Bearer_authorization_with_access_token()
{
var (client, handler) = MockedOAuth2Client.Create();
handler.When(HttpMethod.Post, EndPoints.Token.ToString())
.Respond("application/json", ApiFixtures.OAuth2TokenResult);
await client.UpdateTokenAsync(OAuth2TokenQuery.GrantType.RefreshToken);

handler.Expect(HttpMethod.Get, EndPoints.Me.ToString())
.WithHeaders("Authorization", "Bearer abc-access")
.Respond("application/json", ApiFixtures.MeGet);

var user = await client.me.GetUserAsync();

await Assert.That(user.account_id).IsEqualTo(123);
handler.VerifyNoOutstandingExpectation();
}

[Test]
public async Task ClientName_returns_class_name()
{
var (client, _) = MockedOAuth2Client.Create();
await Assert.That(client.clientName).IsEqualTo(nameof(OAuth2Client));
}
}
Loading
Loading