chore: initial commit
This commit is contained in:
117
.gitignore
vendored
Normal file
117
.gitignore
vendored
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
|
||||||
|
# Created by https://www.gitignore.io/api/dotnetcore,jetbrains+all,visualstudiocode
|
||||||
|
# Edit at https://www.gitignore.io/?templates=dotnetcore,jetbrains+all,visualstudiocode
|
||||||
|
|
||||||
|
### DotnetCore ###
|
||||||
|
# .NET Core build folders
|
||||||
|
/bin
|
||||||
|
/obj
|
||||||
|
|
||||||
|
# Common node modules locations
|
||||||
|
/node_modules
|
||||||
|
/wwwroot/node_modules
|
||||||
|
|
||||||
|
|
||||||
|
### JetBrains+all ###
|
||||||
|
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
|
||||||
|
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||||
|
|
||||||
|
# User-specific stuff
|
||||||
|
.idea/**/workspace.xml
|
||||||
|
.idea/**/tasks.xml
|
||||||
|
.idea/**/usage.statistics.xml
|
||||||
|
.idea/**/dictionaries
|
||||||
|
.idea/**/shelf
|
||||||
|
|
||||||
|
# Generated files
|
||||||
|
.idea/**/contentModel.xml
|
||||||
|
|
||||||
|
# Sensitive or high-churn files
|
||||||
|
.idea/**/dataSources/
|
||||||
|
.idea/**/dataSources.ids
|
||||||
|
.idea/**/dataSources.local.xml
|
||||||
|
.idea/**/sqlDataSources.xml
|
||||||
|
.idea/**/dynamic.xml
|
||||||
|
.idea/**/uiDesigner.xml
|
||||||
|
.idea/**/dbnavigator.xml
|
||||||
|
|
||||||
|
# Gradle
|
||||||
|
.idea/**/gradle.xml
|
||||||
|
.idea/**/libraries
|
||||||
|
|
||||||
|
# Gradle and Maven with auto-import
|
||||||
|
# When using Gradle or Maven with auto-import, you should exclude module files,
|
||||||
|
# since they will be recreated, and may cause churn. Uncomment if using
|
||||||
|
# auto-import.
|
||||||
|
# .idea/modules.xml
|
||||||
|
# .idea/*.iml
|
||||||
|
# .idea/modules
|
||||||
|
# *.iml
|
||||||
|
# *.ipr
|
||||||
|
|
||||||
|
# CMake
|
||||||
|
cmake-build-*/
|
||||||
|
|
||||||
|
# Mongo Explorer plugin
|
||||||
|
.idea/**/mongoSettings.xml
|
||||||
|
|
||||||
|
# File-based project format
|
||||||
|
*.iws
|
||||||
|
|
||||||
|
# IntelliJ
|
||||||
|
out/
|
||||||
|
|
||||||
|
# mpeltonen/sbt-idea plugin
|
||||||
|
.idea_modules/
|
||||||
|
|
||||||
|
# JIRA plugin
|
||||||
|
atlassian-ide-plugin.xml
|
||||||
|
|
||||||
|
# Cursive Clojure plugin
|
||||||
|
.idea/replstate.xml
|
||||||
|
|
||||||
|
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||||
|
com_crashlytics_export_strings.xml
|
||||||
|
crashlytics.properties
|
||||||
|
crashlytics-build.properties
|
||||||
|
fabric.properties
|
||||||
|
|
||||||
|
# Editor-based Rest Client
|
||||||
|
.idea/httpRequests
|
||||||
|
|
||||||
|
# Android studio 3.1+ serialized cache file
|
||||||
|
.idea/caches/build_file_checksums.ser
|
||||||
|
|
||||||
|
### JetBrains+all Patch ###
|
||||||
|
# Ignores the whole .idea folder and all .iml files
|
||||||
|
# See https://github.com/joeblau/gitignore.io/issues/186 and https://github.com/joeblau/gitignore.io/issues/360
|
||||||
|
|
||||||
|
.idea/
|
||||||
|
|
||||||
|
# Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-249601023
|
||||||
|
|
||||||
|
*.iml
|
||||||
|
modules.xml
|
||||||
|
.idea/misc.xml
|
||||||
|
*.ipr
|
||||||
|
|
||||||
|
# Sonarlint plugin
|
||||||
|
.idea/sonarlint
|
||||||
|
|
||||||
|
### VisualStudioCode ###
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/settings.json
|
||||||
|
!.vscode/tasks.json
|
||||||
|
!.vscode/launch.json
|
||||||
|
!.vscode/extensions.json
|
||||||
|
|
||||||
|
### VisualStudioCode Patch ###
|
||||||
|
# Ignore all local history of files
|
||||||
|
.history
|
||||||
|
|
||||||
|
# End of https://www.gitignore.io/api/dotnetcore,jetbrains+all,visualstudiocode
|
||||||
|
publish.sh
|
||||||
|
tests/bin
|
||||||
|
tests/obj
|
||||||
|
src/obj
|
||||||
|
src/bin
|
||||||
18
.gitlab-ci.yml
Normal file
18
.gitlab-ci.yml
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
stages:
|
||||||
|
- test
|
||||||
|
- publish
|
||||||
|
|
||||||
|
running tests for tag:
|
||||||
|
image: mcr.microsoft.com/dotnet/core/sdk:3.1
|
||||||
|
stage: test
|
||||||
|
script:
|
||||||
|
- dotnet test ./tests
|
||||||
|
|
||||||
|
publish to nuget:
|
||||||
|
only:
|
||||||
|
- /^\d*.\d*.\d*$/ # gets triggered if the commit tag is in the form n.n.n where n is any number
|
||||||
|
image: mcr.microsoft.com/dotnet/core/sdk:3.1
|
||||||
|
stage: publish
|
||||||
|
script:
|
||||||
|
- dotnet pack src -o ./packaged
|
||||||
|
- dotnet nuget push ./packaged/*.nupkg -k $NUGET_API_KEY -s https://api.nuget.org/v3/index.json
|
||||||
48
Novaloop.PaymoApi.sln
Normal file
48
Novaloop.PaymoApi.sln
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio 15
|
||||||
|
VisualStudioVersion = 15.0.26124.0
|
||||||
|
MinimumVisualStudioVersion = 15.0.26124.0
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Novaloop.PaymoApi", "src\Novaloop.PaymoApi.csproj", "{A9612B7C-67C1-4B6B-8260-167079A31FAF}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Novaloop.PaymoApi.Tests", "tests\Novaloop.PaymoApi.Tests.csproj", "{202BCB4F-78AF-4E9A-B286-C3147374EB53}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Debug|x64 = Debug|x64
|
||||||
|
Debug|x86 = Debug|x86
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
Release|x64 = Release|x64
|
||||||
|
Release|x86 = Release|x86
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{A9612B7C-67C1-4B6B-8260-167079A31FAF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{A9612B7C-67C1-4B6B-8260-167079A31FAF}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{A9612B7C-67C1-4B6B-8260-167079A31FAF}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{A9612B7C-67C1-4B6B-8260-167079A31FAF}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{A9612B7C-67C1-4B6B-8260-167079A31FAF}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{A9612B7C-67C1-4B6B-8260-167079A31FAF}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
|
{A9612B7C-67C1-4B6B-8260-167079A31FAF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{A9612B7C-67C1-4B6B-8260-167079A31FAF}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{A9612B7C-67C1-4B6B-8260-167079A31FAF}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{A9612B7C-67C1-4B6B-8260-167079A31FAF}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{A9612B7C-67C1-4B6B-8260-167079A31FAF}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{A9612B7C-67C1-4B6B-8260-167079A31FAF}.Release|x86.Build.0 = Release|Any CPU
|
||||||
|
{202BCB4F-78AF-4E9A-B286-C3147374EB53}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{202BCB4F-78AF-4E9A-B286-C3147374EB53}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{202BCB4F-78AF-4E9A-B286-C3147374EB53}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{202BCB4F-78AF-4E9A-B286-C3147374EB53}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{202BCB4F-78AF-4E9A-B286-C3147374EB53}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{202BCB4F-78AF-4E9A-B286-C3147374EB53}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
|
{202BCB4F-78AF-4E9A-B286-C3147374EB53}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{202BCB4F-78AF-4E9A-B286-C3147374EB53}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{202BCB4F-78AF-4E9A-B286-C3147374EB53}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{202BCB4F-78AF-4E9A-B286-C3147374EB53}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{202BCB4F-78AF-4E9A-B286-C3147374EB53}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{202BCB4F-78AF-4E9A-B286-C3147374EB53}.Release|x86.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
||||||
50
README.md
Normal file
50
README.md
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
# Novaloop.PaymoApi - Accessing Paymo Api
|
||||||
|
|
||||||
|
**Novaloop.PaymoApi** allows to access the paymo API.
|
||||||
|
|
||||||
|
## Implemented Methods
|
||||||
|
|
||||||
|
- Get an existing Task
|
||||||
|
- Create a new Task
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
### Startup.cs
|
||||||
|
|
||||||
|
The api client is added with the following configuration inside `ConfigureServices`.
|
||||||
|
See https://github.com/paymoapp/api/blob/master/sections/authentication.md#using-sessions for how to acquire an api key.
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
public void ConfigureServices(IServiceCollection services)
|
||||||
|
{
|
||||||
|
services.AddPaymoApi(options =>
|
||||||
|
{
|
||||||
|
options.ApiKey = "your-api-key";
|
||||||
|
});
|
||||||
|
services.AddControllers();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Usage
|
||||||
|
|
||||||
|
Now the Api Services can be injected via dependency injection inside controllers / services:
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
[ApiController]
|
||||||
|
[Route("[controller]")]
|
||||||
|
public class ExampleController : ControllerBase
|
||||||
|
{
|
||||||
|
private readonly IPaymoTaskApiService _paymoTaskService;
|
||||||
|
|
||||||
|
public ExampleController(IPaymoTaskApiService paymoTaskService)
|
||||||
|
{
|
||||||
|
_paymoTaskService = paymoTaskService;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
public async Task<IActionResult> Get()
|
||||||
|
{
|
||||||
|
return Ok(await _paymoTaskService.GetTask(11));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
2
pack.sh
Executable file
2
pack.sh
Executable file
@@ -0,0 +1,2 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
dotnet pack src -o ../local-nuget-packages
|
||||||
14
src/Exceptions/PaymoApiException.cs
Normal file
14
src/Exceptions/PaymoApiException.cs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Novaloop.PaymoApi.Exceptions
|
||||||
|
{
|
||||||
|
public class PaymoApiException : Exception
|
||||||
|
{
|
||||||
|
public PaymoApiException(int statusCode, string message) : base($"[{statusCode}]: {message})")
|
||||||
|
{
|
||||||
|
StatusCode = statusCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int StatusCode { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
37
src/Extensions/HttpClientExtensions.cs
Normal file
37
src/Extensions/HttpClientExtensions.cs
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
using System;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Net.Http.Headers;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Novaloop.PaymoApi.Extensions
|
||||||
|
{
|
||||||
|
internal static class HttpClientExtensions
|
||||||
|
{
|
||||||
|
internal static void SetApiKeyHeader(this HttpClient client, string apiKey)
|
||||||
|
{
|
||||||
|
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Base64Encode($"{apiKey}:random"));
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static async Task<HttpResponseMessage> PatchAsync(this HttpClient client, string uri, HttpContent content)
|
||||||
|
{
|
||||||
|
var method = new HttpMethod("PATCH");
|
||||||
|
if (client.BaseAddress is null)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Can not handle 'BaseAddress' null value configuration.");
|
||||||
|
}
|
||||||
|
|
||||||
|
var request = new HttpRequestMessage(method, new Uri(CombineBaseUrlWithSegment(client.BaseAddress.ToString(), uri))) {Content = content};
|
||||||
|
return await client.SendAsync(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string CombineBaseUrlWithSegment(string uri1, string uri2)
|
||||||
|
{
|
||||||
|
return $"{uri1.TrimEnd('/')}/{uri2.TrimStart('/')}";
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string Base64Encode(string plainText)
|
||||||
|
{
|
||||||
|
return Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(plainText));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
17
src/Extensions/HttpResponseMessageExtensions.cs
Normal file
17
src/Extensions/HttpResponseMessageExtensions.cs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
using System.Net.Http;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Novaloop.PaymoApi.Exceptions;
|
||||||
|
|
||||||
|
namespace Novaloop.PaymoApi.Extensions
|
||||||
|
{
|
||||||
|
internal static class HttpResponseMessageExtensions
|
||||||
|
{
|
||||||
|
internal static async Task ThrowExceptionWithDetailsIfUnsuccessful(this HttpResponseMessage response)
|
||||||
|
{
|
||||||
|
if (!response.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
throw new PaymoApiException((int) response.StatusCode, await response.Content.ReadAsStringAsync());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
20
src/Extensions/PaymoApiExtensions.cs
Normal file
20
src/Extensions/PaymoApiExtensions.cs
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
using System;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
using Novaloop.PaymoApi.Shared;
|
||||||
|
using Novaloop.PaymoApi.Tasks;
|
||||||
|
|
||||||
|
namespace Novaloop.PaymoApi.Extensions
|
||||||
|
{
|
||||||
|
public static class PaymoApiExtensions
|
||||||
|
{
|
||||||
|
public static IServiceCollection AddPaymoApi(this IServiceCollection services, Action<PaymoApiOptions> options)
|
||||||
|
{
|
||||||
|
services.Configure(options);
|
||||||
|
var resolvedOptions = (IOptions<PaymoApiOptions>) services.BuildServiceProvider().GetService(typeof(IOptions<PaymoApiOptions>));
|
||||||
|
services.AddHttpClient<PaymoApiClient>(client => { client.BaseAddress = new Uri(resolvedOptions.Value.BaseUrl); });
|
||||||
|
services.AddTransient<IPaymoTasksApiService, PaymoTasksApiService>();
|
||||||
|
return services;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
8
src/Extensions/PaymoApiOptions.cs
Normal file
8
src/Extensions/PaymoApiOptions.cs
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
namespace Novaloop.PaymoApi.Extensions
|
||||||
|
{
|
||||||
|
public class PaymoApiOptions
|
||||||
|
{
|
||||||
|
public string BaseUrl { get; set; } = "https://app.paymoapp.com/api";
|
||||||
|
public string ApiToken { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
19
src/Novaloop.PaymoApi.csproj
Normal file
19
src/Novaloop.PaymoApi.csproj
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>netstandard2.0</TargetFramework>
|
||||||
|
<PackageId>Novaloop.PaymoApi</PackageId>
|
||||||
|
<title>Access your paymo instance for asp.net core</title>
|
||||||
|
<PackageTags>api;paymo;asp.net core;</PackageTags>
|
||||||
|
<Version>0.1.0</Version>
|
||||||
|
<Authors>Matthias Langhard</Authors>
|
||||||
|
<Company>Novaloop AG</Company>
|
||||||
|
<PackageProjectUrl>https://gitlab.com/novaloop-oss/novaloop.paymoapi</PackageProjectUrl>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="5.2.7" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Http" Version="5.0.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
14
src/Shared/PaymoApiClient.cs
Normal file
14
src/Shared/PaymoApiClient.cs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
using System.Net.Http;
|
||||||
|
|
||||||
|
namespace Novaloop.PaymoApi.Shared
|
||||||
|
{
|
||||||
|
public class PaymoApiClient
|
||||||
|
{
|
||||||
|
public PaymoApiClient(HttpClient client)
|
||||||
|
{
|
||||||
|
Client = client;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpClient Client { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
11
src/Tasks/IPaymoTasksApiService.cs
Normal file
11
src/Tasks/IPaymoTasksApiService.cs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
using System.Threading.Tasks;
|
||||||
|
using Novaloop.PaymoApi.Tasks.Models;
|
||||||
|
|
||||||
|
namespace Novaloop.PaymoApi.Tasks
|
||||||
|
{
|
||||||
|
public interface IPaymoTasksApiService
|
||||||
|
{
|
||||||
|
Task<GetTasksResponse> GetTask(int taskId);
|
||||||
|
Task<CreateTaskResponse> CreateTask(CreateTaskRequest createTask);
|
||||||
|
}
|
||||||
|
}
|
||||||
12
src/Tasks/Models/CreateTaskRequest.cs
Normal file
12
src/Tasks/Models/CreateTaskRequest.cs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Novaloop.PaymoApi.Tasks.Models
|
||||||
|
{
|
||||||
|
public class CreateTaskRequest
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
|
public string Description { get; set; }
|
||||||
|
public int TasklistId { get; set; }
|
||||||
|
public List<int> Users { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
7
src/Tasks/Models/CreateTaskResponse.cs
Normal file
7
src/Tasks/Models/CreateTaskResponse.cs
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
namespace Novaloop.PaymoApi.Tasks.Models
|
||||||
|
{
|
||||||
|
public class CreateTaskResponse : PaymoTask
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
9
src/Tasks/Models/GetTasksResponse.cs
Normal file
9
src/Tasks/Models/GetTasksResponse.cs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Novaloop.PaymoApi.Tasks.Models
|
||||||
|
{
|
||||||
|
public class GetTasksResponse
|
||||||
|
{
|
||||||
|
public IEnumerable<PaymoTask> Tasks { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
25
src/Tasks/Models/PaymoTask.cs
Normal file
25
src/Tasks/Models/PaymoTask.cs
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Novaloop.PaymoApi.Tasks.Models
|
||||||
|
{
|
||||||
|
public class PaymoTask
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
public string Code { get; set; }
|
||||||
|
public int ProjectId { get; set; }
|
||||||
|
public int TasklistId { get; set; }
|
||||||
|
public int UserId { get; set; }
|
||||||
|
public bool Complete { get; set; }
|
||||||
|
public bool Billable { get; set; }
|
||||||
|
public int Seq { get; set; }
|
||||||
|
public string Description { get; set; }
|
||||||
|
public object PricePerHour { get; set; }
|
||||||
|
public object DueDate { get; set; }
|
||||||
|
public object BudgetHours { get; set; }
|
||||||
|
public List<int> Users { get; set; }
|
||||||
|
public DateTime CreatedOn { get; set; }
|
||||||
|
public DateTime UpdatedOn { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
44
src/Tasks/PaymoTasksApiService.cs
Normal file
44
src/Tasks/PaymoTasksApiService.cs
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
using System.Net.Http;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
using Novaloop.PaymoApi.Extensions;
|
||||||
|
using Novaloop.PaymoApi.Shared;
|
||||||
|
using Novaloop.PaymoApi.Tasks.Models;
|
||||||
|
|
||||||
|
namespace Novaloop.PaymoApi.Tasks
|
||||||
|
{
|
||||||
|
public class PaymoTasksApiService : IPaymoTasksApiService
|
||||||
|
{
|
||||||
|
private readonly PaymoApiOptions _options;
|
||||||
|
private readonly HttpClient _client;
|
||||||
|
|
||||||
|
public PaymoTasksApiService(PaymoApiClient paymoApiClient, IOptions<PaymoApiOptions> options)
|
||||||
|
{
|
||||||
|
_options = options.Value;
|
||||||
|
_client = paymoApiClient.Client;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get an existing Task
|
||||||
|
/// </summary>
|
||||||
|
public async Task<GetTasksResponse> GetTask(int taskId)
|
||||||
|
{
|
||||||
|
_client.SetApiKeyHeader(_options.ApiToken);
|
||||||
|
var response = await _client.GetAsync($"/tasks/{taskId}");
|
||||||
|
await response.ThrowExceptionWithDetailsIfUnsuccessful();
|
||||||
|
return await response.Content.ReadAsAsync<GetTasksResponse>();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new Task
|
||||||
|
/// </summary>
|
||||||
|
public async Task<CreateTaskResponse> CreateTask(CreateTaskRequest createTaskRequest)
|
||||||
|
{
|
||||||
|
_client.SetApiKeyHeader(_options.ApiToken);
|
||||||
|
var response = await _client.PostAsJsonAsync("/tasks", createTaskRequest);
|
||||||
|
await response.ThrowExceptionWithDetailsIfUnsuccessful();
|
||||||
|
return await response.Content.ReadAsAsync<CreateTaskResponse>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
22
tests/Novaloop.PaymoApi.Tests.csproj
Normal file
22
tests/Novaloop.PaymoApi.Tests.csproj
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net5.0</TargetFramework>
|
||||||
|
|
||||||
|
<IsPackable>false</IsPackable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.7.1" />
|
||||||
|
<PackageReference Include="xunit" Version="2.4.1" />
|
||||||
|
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="coverlet.collector" Version="1.3.0">
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
</PackageReference>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
13
tests/UnitTest1.cs
Normal file
13
tests/UnitTest1.cs
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Novaloop.PaymoApi.Tests
|
||||||
|
{
|
||||||
|
public class UnitTest1
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public void Test1()
|
||||||
|
{
|
||||||
|
Assert.True(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user