mirror of
https://github.com/Smaug123/WoofWare.Myriad
synced 2025-10-06 12:38:40 +00:00
Bump deps (#54)
This commit is contained in:
21
WoofWare.Myriad.Plugins.Test/HttpClient.fs
Normal file
21
WoofWare.Myriad.Plugins.Test/HttpClient.fs
Normal file
@@ -0,0 +1,21 @@
|
||||
namespace WoofWare.Myriad.Plugins.Test
|
||||
|
||||
open System.Net.Http
|
||||
|
||||
/// Simple implementation of an HttpClient.
|
||||
type HttpClientMock (result : HttpRequestMessage -> Async<HttpResponseMessage>) =
|
||||
inherit HttpClient ()
|
||||
|
||||
override this.SendAsync (message, ct) =
|
||||
Async.StartAsTask (result message, cancellationToken = ct)
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
module HttpClientMock =
|
||||
let makeNoUri (handler : HttpRequestMessage -> Async<HttpResponseMessage>) =
|
||||
let result = new HttpClientMock (handler)
|
||||
result
|
||||
|
||||
let make (baseUrl : System.Uri) (handler : HttpRequestMessage -> Async<HttpResponseMessage>) =
|
||||
let result = makeNoUri handler
|
||||
result.BaseAddress <- baseUrl
|
||||
result
|
264
WoofWare.Myriad.Plugins.Test/PureGymDtos.fs
Normal file
264
WoofWare.Myriad.Plugins.Test/PureGymDtos.fs
Normal file
@@ -0,0 +1,264 @@
|
||||
namespace WoofWare.Myriad.Plugins.Test
|
||||
|
||||
open PureGym
|
||||
open System
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
module PureGymDtos =
|
||||
|
||||
let gymOpeningHoursCases =
|
||||
[
|
||||
"""{"openingHours": [], "isAlwaysOpen": false}""",
|
||||
{
|
||||
GymOpeningHours.OpeningHours = []
|
||||
IsAlwaysOpen = false
|
||||
}
|
||||
"""{"openingHours": ["something"], "isAlwaysOpen": false}""",
|
||||
{
|
||||
GymOpeningHours.OpeningHours = [ "something" ]
|
||||
IsAlwaysOpen = false
|
||||
}
|
||||
]
|
||||
|
||||
let gymAccessOptionsCases =
|
||||
List.allPairs [ true ; false ] [ true ; false ]
|
||||
|> List.map (fun (a, b) ->
|
||||
let s = sprintf """{"pinAccess": %b, "qrCodeAccess": %b}""" a b
|
||||
|
||||
s,
|
||||
{
|
||||
GymAccessOptions.PinAccess = a
|
||||
QrCodeAccess = b
|
||||
}
|
||||
)
|
||||
|
||||
let gymAddressCases =
|
||||
[
|
||||
"""{"addressLine1": "", "postCode": "hi", "town": ""}""",
|
||||
{
|
||||
GymAddress.AddressLine1 = ""
|
||||
AddressLine2 = None
|
||||
AddressLine3 = None
|
||||
County = None
|
||||
Postcode = "hi"
|
||||
Town = ""
|
||||
}
|
||||
"""{"addressLine1": "", "addressLine2": null, "postCode": "hi", "town": ""}""",
|
||||
{
|
||||
GymAddress.AddressLine1 = ""
|
||||
AddressLine2 = None
|
||||
AddressLine3 = None
|
||||
County = None
|
||||
Postcode = "hi"
|
||||
Town = ""
|
||||
}
|
||||
]
|
||||
|
||||
let gymLocationCases =
|
||||
[
|
||||
"""{"latitude": 1.0, "longitude": 3.0}""",
|
||||
{
|
||||
GymLocation.Latitude = 1.0
|
||||
Longitude = 3.0
|
||||
}
|
||||
]
|
||||
|
||||
let gymCases =
|
||||
let ovalJson =
|
||||
"""{"name":"London Oval","id":19,"status":2,"address":{"addressLine1":"Canterbury Court","addressLine2":"Units 4, 4A, 5 And 5A","addressLine3":"Kennington Park","town":"LONDON","county":null,"postcode":"SW9 6DE"},"phoneNumber":"+44 3444770005","emailAddress":"info.londonoval@puregym.com","staffMembers":null,"gymOpeningHours":{"isAlwaysOpen":true,"openingHours":[]},"reasonsToJoin":null,"accessOptions":{"pinAccess":true,"qrCodeAccess":true},"virtualTourUrl":null,"personalTrainersUrl":null,"webViewUrl":null,"floorPlanUrl":null,"location":{"longitude":"-0.110252","latitude":"51.480401"},"timeZone":"Europe/London","reopenDate":"2021-04-12T00:00:00+01 Europe/London"}"""
|
||||
|
||||
let oval =
|
||||
{
|
||||
Gym.Name = "London Oval"
|
||||
Id = 19
|
||||
Status = 2
|
||||
Address =
|
||||
{
|
||||
AddressLine1 = "Canterbury Court"
|
||||
AddressLine2 = Some "Units 4, 4A, 5 And 5A"
|
||||
AddressLine3 = Some "Kennington Park"
|
||||
Town = "LONDON"
|
||||
County = None
|
||||
Postcode = "SW9 6DE"
|
||||
}
|
||||
PhoneNumber = "+44 3444770005"
|
||||
EmailAddress = "info.londonoval@puregym.com"
|
||||
GymOpeningHours =
|
||||
{
|
||||
IsAlwaysOpen = true
|
||||
OpeningHours = []
|
||||
}
|
||||
AccessOptions =
|
||||
{
|
||||
PinAccess = true
|
||||
QrCodeAccess = true
|
||||
}
|
||||
Location =
|
||||
{
|
||||
Longitude = -0.110252
|
||||
Latitude = 51.480401
|
||||
}
|
||||
TimeZone = "Europe/London"
|
||||
ReopenDate = "2021-04-12T00:00:00+01 Europe/London"
|
||||
}
|
||||
|
||||
[ ovalJson, oval ]
|
||||
|
||||
let memberCases =
|
||||
let me =
|
||||
{
|
||||
Id = 1234567
|
||||
CompoundMemberId = "12A123456"
|
||||
FirstName = "Patrick"
|
||||
LastName = "Stevens"
|
||||
HomeGymId = 19
|
||||
HomeGymName = "London Oval"
|
||||
EmailAddress = "someone@somewhere"
|
||||
GymAccessPin = "00000000"
|
||||
DateOfBirth = DateOnly (1994, 01, 02)
|
||||
MobileNumber = "+44 1234567"
|
||||
Postcode = "W1A 1AA"
|
||||
MembershipName = "Corporate"
|
||||
MembershipLevel = 12
|
||||
SuspendedReason = 0
|
||||
MemberStatus = 2
|
||||
}
|
||||
|
||||
let meJson =
|
||||
"""{
|
||||
"id": 1234567,
|
||||
"compoundMemberId": "12A123456",
|
||||
"firstName": "Patrick",
|
||||
"lastName": "Stevens",
|
||||
"homeGymId": 19,
|
||||
"homeGymName": "London Oval",
|
||||
"emailAddress": "someone@somewhere",
|
||||
"gymAccessPin": "00000000",
|
||||
"dateofBirth": "1994-01-02",
|
||||
"mobileNumber": "+44 1234567",
|
||||
"postCode": "W1A 1AA",
|
||||
"membershipName": "Corporate",
|
||||
"membershipLevel": 12,
|
||||
"suspendedReason": 0,
|
||||
"memberStatus": 2
|
||||
}"""
|
||||
|
||||
[ meJson, me ]
|
||||
|
||||
let gymAttendanceCases =
|
||||
let json =
|
||||
"""{
|
||||
"description": "65",
|
||||
"totalPeopleInGym": 65,
|
||||
"totalPeopleInClasses": 2,
|
||||
"totalPeopleSuffix": null,
|
||||
"isApproximate": false,
|
||||
"attendanceTime": "2023-12-27T18:54:09.5101697",
|
||||
"lastRefreshed": "2023-12-27T18:54:09.5101697Z",
|
||||
"lastRefreshedPeopleInClasses": "2023-12-27T18:50:26.0782286Z",
|
||||
"maximumCapacity": 0
|
||||
}"""
|
||||
|
||||
let expected =
|
||||
{
|
||||
Description = "65"
|
||||
TotalPeopleInGym = 65
|
||||
TotalPeopleInClasses = 2
|
||||
TotalPeopleSuffix = None
|
||||
IsApproximate = false
|
||||
AttendanceTime =
|
||||
DateTime (2023, 12, 27, 18, 54, 09, 510, 169, DateTimeKind.Utc)
|
||||
+ TimeSpan.FromTicks 7L
|
||||
LastRefreshed =
|
||||
DateTime (2023, 12, 27, 18, 54, 09, 510, 169, DateTimeKind.Utc)
|
||||
+ TimeSpan.FromTicks 7L
|
||||
LastRefreshedPeopleInClasses =
|
||||
DateTime (2023, 12, 27, 18, 50, 26, 078, 228, DateTimeKind.Utc)
|
||||
+ TimeSpan.FromTicks 6L
|
||||
MaximumCapacity = 0
|
||||
}
|
||||
|
||||
[ json, expected ]
|
||||
|
||||
let memberActivityDtoCases =
|
||||
let json =
|
||||
"""{"totalDuration":2217,"averageDuration":48,"totalVisits":46,"totalClasses":0,"isEstimated":false,"lastRefreshed":"2023-12-27T19:00:56.0309892Z"}"""
|
||||
|
||||
let value =
|
||||
{
|
||||
TotalDuration = 2217
|
||||
AverageDuration = 48
|
||||
TotalVisits = 46
|
||||
TotalClasses = 0
|
||||
IsEstimated = false
|
||||
LastRefreshed =
|
||||
DateTime (2023, 12, 27, 19, 00, 56, 030, 989, DateTimeKind.Utc)
|
||||
+ TimeSpan.FromTicks 2L
|
||||
}
|
||||
|
||||
[ json, value ]
|
||||
|
||||
let sessionsCases =
|
||||
let json =
|
||||
"""{
|
||||
"Summary":{"Total":{"Activities":0,"Visits":10,"Duration":445},"ThisWeek":{"Activities":0,"Visits":0,"Duration":0}},
|
||||
"Visits":[
|
||||
{"IsDurationEstimated":false,"Gym":{"Id":19,"Name":"London Oval","Status":"Blocked","Location":null,"GymAccess":null,"ContactInfo":null,"TimeZone":null},"StartTime":"2023-12-21T10:12:00","Duration":50,"Name":null},
|
||||
{"IsDurationEstimated":false,"Gym":{"Id":19,"Name":"London Oval","Status":"Blocked","Location":null,"GymAccess":null,"ContactInfo":null,"TimeZone":null},"StartTime":"2023-12-20T12:05:00","Duration":80,"Name":null},
|
||||
{"IsDurationEstimated":false,"Gym":{"Id":19,"Name":"London Oval","Status":"Blocked","Location":null,"GymAccess":null,"ContactInfo":null,"TimeZone":null},"StartTime":"2023-12-17T19:37:00","Duration":46,"Name":null},
|
||||
{"IsDurationEstimated":false,"Gym":{"Id":19,"Name":"London Oval","Status":"Blocked","Location":null,"GymAccess":null,"ContactInfo":null,"TimeZone":null},"StartTime":"2023-12-16T12:19:00","Duration":37,"Name":null},
|
||||
{"IsDurationEstimated":false,"Gym":{"Id":19,"Name":"London Oval","Status":"Blocked","Location":null,"GymAccess":null,"ContactInfo":null,"TimeZone":null},"StartTime":"2023-12-15T11:14:00","Duration":47,"Name":null},
|
||||
{"IsDurationEstimated":false,"Gym":{"Id":19,"Name":"London Oval","Status":"Blocked","Location":null,"GymAccess":null,"ContactInfo":null,"TimeZone":null},"StartTime":"2023-12-13T10:30:00","Duration":36,"Name":null},
|
||||
{"IsDurationEstimated":false,"Gym":{"Id":19,"Name":"London Oval","Status":"Blocked","Location":null,"GymAccess":null,"ContactInfo":null,"TimeZone":null},"StartTime":"2023-12-10T16:18:00","Duration":32,"Name":null},
|
||||
{"IsDurationEstimated":false,"Gym":{"Id":19,"Name":"London Oval","Status":"Blocked","Location":null,"GymAccess":null,"ContactInfo":null,"TimeZone":null},"StartTime":"2023-12-05T22:36:00","Duration":40,"Name":null},
|
||||
{"IsDurationEstimated":false,"Gym":{"Id":19,"Name":"London Oval","Status":"Blocked","Location":null,"GymAccess":null,"ContactInfo":null,"TimeZone":null},"StartTime":"2023-12-03T17:59:00","Duration":48,"Name":null},
|
||||
{"IsDurationEstimated":false,"Gym":{"Id":19,"Name":"London Oval","Status":"Blocked","Location":null,"GymAccess":null,"ContactInfo":null,"TimeZone":null},"StartTime":"2023-12-01T21:41:00","Duration":29,"Name":null}],
|
||||
"Activities":[]}
|
||||
"""
|
||||
|
||||
let singleVisit startTime duration =
|
||||
{
|
||||
IsDurationEstimated = false
|
||||
Gym =
|
||||
{
|
||||
Id = 19
|
||||
Name = "London Oval"
|
||||
Status = "Blocked"
|
||||
}
|
||||
StartTime = startTime
|
||||
Duration = duration
|
||||
}
|
||||
|
||||
let expected =
|
||||
{
|
||||
Summary =
|
||||
{
|
||||
Total =
|
||||
{
|
||||
Activities = 0
|
||||
Visits = 10
|
||||
Duration = 445
|
||||
}
|
||||
ThisWeek =
|
||||
{
|
||||
Activities = 0
|
||||
Visits = 0
|
||||
Duration = 0
|
||||
}
|
||||
}
|
||||
Visits =
|
||||
[
|
||||
singleVisit (DateTime (2023, 12, 21, 10, 12, 00)) 50
|
||||
singleVisit (DateTime (2023, 12, 20, 12, 05, 00)) 80
|
||||
singleVisit (DateTime (2023, 12, 17, 19, 37, 00)) 46
|
||||
singleVisit (DateTime (2023, 12, 16, 12, 19, 00)) 37
|
||||
singleVisit (DateTime (2023, 12, 15, 11, 14, 00)) 47
|
||||
singleVisit (DateTime (2023, 12, 13, 10, 30, 00)) 36
|
||||
singleVisit (DateTime (2023, 12, 10, 16, 18, 00)) 32
|
||||
singleVisit (DateTime (2023, 12, 05, 22, 36, 00)) 40
|
||||
singleVisit (DateTime (2023, 12, 03, 17, 59, 00)) 48
|
||||
singleVisit (DateTime (2023, 12, 01, 21, 41, 00)) 29
|
||||
]
|
||||
}
|
||||
|
||||
[ json, expected ]
|
@@ -0,0 +1,62 @@
|
||||
namespace WoofWare.Myriad.Plugins.Test
|
||||
|
||||
open System
|
||||
open System.Net
|
||||
open System.Net.Http
|
||||
open NUnit.Framework
|
||||
open FsUnitTyped
|
||||
open PureGym
|
||||
|
||||
[<TestFixture>]
|
||||
module TestAllowAnyStatusCode =
|
||||
|
||||
[<Test>]
|
||||
let ``Without AllowAnyStatusCode we throw`` () =
|
||||
let proc (message : HttpRequestMessage) : HttpResponseMessage Async =
|
||||
async {
|
||||
message.Method |> shouldEqual HttpMethod.Get
|
||||
let content = new StringContent ("nothing was here :(")
|
||||
let resp = new HttpResponseMessage (HttpStatusCode.NotFound)
|
||||
resp.Content <- content
|
||||
return resp
|
||||
}
|
||||
|
||||
use client = HttpClientMock.make (Uri "https://example.com") proc
|
||||
let api = PureGymApi.make client
|
||||
|
||||
let exc =
|
||||
async {
|
||||
let! message = Async.AwaitTask (api.GetWithoutAnyReturnCode ()) |> Async.Catch
|
||||
|
||||
match message with
|
||||
| Choice1Of2 _ -> return failwith "test failure"
|
||||
| Choice2Of2 exc -> return exc
|
||||
}
|
||||
|> Async.RunSynchronously
|
||||
|
||||
let exc =
|
||||
match exc with
|
||||
| :? AggregateException as exc -> exc
|
||||
| exc -> failwith $"Test failure: expected AggregateException, got %+A{exc}"
|
||||
|
||||
match exc.InnerException with
|
||||
| :? HttpRequestException as exc -> exc.Message.Contains "404 (Not Found)" |> shouldEqual true
|
||||
| e -> failwith $"Test failure: %+A{e}"
|
||||
|
||||
[<Test>]
|
||||
let ``With AllowAnyStatusCode we do not throw`` () =
|
||||
let proc (message : HttpRequestMessage) : HttpResponseMessage Async =
|
||||
async {
|
||||
message.Method |> shouldEqual HttpMethod.Get
|
||||
let content = new StringContent ("nothing was here :(")
|
||||
let resp = new HttpResponseMessage (HttpStatusCode.NotFound)
|
||||
resp.Content <- content
|
||||
return resp
|
||||
}
|
||||
|
||||
use client = HttpClientMock.make (Uri "https://example.com") proc
|
||||
let api = PureGymApi.make client
|
||||
|
||||
let message = api.GetWithAnyReturnCode().Result
|
||||
message.StatusCode |> shouldEqual HttpStatusCode.NotFound
|
||||
message.Content.ReadAsStringAsync().Result |> shouldEqual "nothing was here :("
|
80
WoofWare.Myriad.Plugins.Test/TestHttpClient/TestBasePath.fs
Normal file
80
WoofWare.Myriad.Plugins.Test/TestHttpClient/TestBasePath.fs
Normal file
@@ -0,0 +1,80 @@
|
||||
namespace WoofWare.Myriad.Plugins.Test
|
||||
|
||||
open System
|
||||
open System.Net
|
||||
open System.Net.Http
|
||||
open NUnit.Framework
|
||||
open PureGym
|
||||
open FsUnitTyped
|
||||
|
||||
[<TestFixture>]
|
||||
module TestBasePath =
|
||||
[<Test>]
|
||||
let ``Base address is respected`` () =
|
||||
let proc (message : HttpRequestMessage) : HttpResponseMessage Async =
|
||||
async {
|
||||
message.Method |> shouldEqual HttpMethod.Get
|
||||
let content = new StringContent (message.RequestUri.ToString ())
|
||||
let resp = new HttpResponseMessage (HttpStatusCode.OK)
|
||||
resp.Content <- content
|
||||
return resp
|
||||
}
|
||||
|
||||
use client = HttpClientMock.makeNoUri proc
|
||||
let api = PureGymApi.make client
|
||||
|
||||
let observedUri = api.GetPathParam("param").Result
|
||||
observedUri |> shouldEqual "https://whatnot.com/endpoint/param"
|
||||
|
||||
[<Test>]
|
||||
let ``Without a base address attr but with BaseAddress on client, request goes through`` () =
|
||||
let proc (message : HttpRequestMessage) : HttpResponseMessage Async =
|
||||
async {
|
||||
message.Method |> shouldEqual HttpMethod.Get
|
||||
let content = new StringContent (message.RequestUri.ToString ())
|
||||
let resp = new HttpResponseMessage (HttpStatusCode.OK)
|
||||
resp.Content <- content
|
||||
return resp
|
||||
}
|
||||
|
||||
use client = HttpClientMock.make (System.Uri "https://baseaddress.com") proc
|
||||
let api = ApiWithoutBaseAddress.make client
|
||||
|
||||
let observedUri = api.GetPathParam("param").Result
|
||||
observedUri |> shouldEqual "https://baseaddress.com/endpoint/param"
|
||||
|
||||
[<Test>]
|
||||
let ``Without a base address attr or BaseAddress on client, request throws`` () =
|
||||
let proc (message : HttpRequestMessage) : HttpResponseMessage Async =
|
||||
async {
|
||||
message.Method |> shouldEqual HttpMethod.Get
|
||||
let content = new StringContent (message.RequestUri.ToString ())
|
||||
let resp = new HttpResponseMessage (HttpStatusCode.OK)
|
||||
resp.Content <- content
|
||||
return resp
|
||||
}
|
||||
|
||||
use client = HttpClientMock.makeNoUri proc
|
||||
let api = ApiWithoutBaseAddress.make client
|
||||
|
||||
let observedExc =
|
||||
async {
|
||||
let! result = api.GetPathParam ("param") |> Async.AwaitTask |> Async.Catch
|
||||
|
||||
match result with
|
||||
| Choice1Of2 _ -> return failwith "test failure"
|
||||
| Choice2Of2 exc -> return exc
|
||||
}
|
||||
|> Async.RunSynchronously
|
||||
|
||||
let observedExc =
|
||||
match observedExc with
|
||||
| :? AggregateException as exc ->
|
||||
match exc.InnerException with
|
||||
| :? ArgumentNullException as exc -> exc
|
||||
| _ -> failwith "test failure"
|
||||
| _ -> failwith "test failure"
|
||||
|
||||
observedExc.Message
|
||||
|> shouldEqual
|
||||
"No base address was supplied on the type, and no BaseAddress was on the HttpClient. (Parameter 'BaseAddress')"
|
105
WoofWare.Myriad.Plugins.Test/TestHttpClient/TestBodyParam.fs
Normal file
105
WoofWare.Myriad.Plugins.Test/TestHttpClient/TestBodyParam.fs
Normal file
@@ -0,0 +1,105 @@
|
||||
namespace WoofWare.Myriad.Plugins.Test
|
||||
|
||||
open System
|
||||
open System.IO
|
||||
open System.Net
|
||||
open System.Net.Http
|
||||
open System.Text.Json.Nodes
|
||||
open NUnit.Framework
|
||||
open PureGym
|
||||
open FsUnitTyped
|
||||
|
||||
[<TestFixture>]
|
||||
module TestBodyParam =
|
||||
|
||||
[<Test>]
|
||||
let ``Body param of string`` () =
|
||||
let proc (message : HttpRequestMessage) : HttpResponseMessage Async =
|
||||
async {
|
||||
message.Method |> shouldEqual HttpMethod.Post
|
||||
let! content = message.Content.ReadAsStringAsync () |> Async.AwaitTask
|
||||
let content = new StringContent (content)
|
||||
let resp = new HttpResponseMessage (HttpStatusCode.OK)
|
||||
resp.Content <- content
|
||||
return resp
|
||||
}
|
||||
|
||||
use client = HttpClientMock.make (Uri "https://example.com") proc
|
||||
let api = PureGymApi.make client
|
||||
|
||||
let observedUri = api.CreateUserString("username?not!url%encoded").Result
|
||||
observedUri |> shouldEqual "username?not!url%encoded"
|
||||
|
||||
[<Test>]
|
||||
let ``Body param of stream`` () =
|
||||
let proc (message : HttpRequestMessage) : HttpResponseMessage Async =
|
||||
async {
|
||||
message.Method |> shouldEqual HttpMethod.Post
|
||||
let! content = message.Content.ReadAsStreamAsync () |> Async.AwaitTask
|
||||
let content = new StreamContent (content)
|
||||
let resp = new HttpResponseMessage (HttpStatusCode.OK)
|
||||
resp.Content <- content
|
||||
return resp
|
||||
}
|
||||
|
||||
let contents = [| 1uy ; 2uy ; 3uy ; 4uy |]
|
||||
|
||||
use client = HttpClientMock.make (Uri "https://example.com") proc
|
||||
let api = PureGymApi.make client
|
||||
|
||||
use stream = new MemoryStream (contents)
|
||||
let observedContent = api.CreateUserStream(stream).Result
|
||||
let buf = Array.zeroCreate 10
|
||||
let written = observedContent.ReadAtLeast (buf.AsSpan (), 5, false)
|
||||
buf |> Array.take written |> shouldEqual contents
|
||||
|
||||
[<Test>]
|
||||
let ``Body param of HttpContent`` () =
|
||||
let mutable observedContent = None
|
||||
|
||||
let proc (message : HttpRequestMessage) : HttpResponseMessage Async =
|
||||
async {
|
||||
message.Method |> shouldEqual HttpMethod.Post
|
||||
let resp = new HttpResponseMessage (HttpStatusCode.OK)
|
||||
observedContent <- Some message.Content
|
||||
resp.Content <- new StringContent ("oh hi")
|
||||
return resp
|
||||
}
|
||||
|
||||
use client = HttpClientMock.make (Uri "https://example.com") proc
|
||||
let api = PureGymApi.make client
|
||||
|
||||
use content = new StringContent ("hello!")
|
||||
|
||||
api.CreateUserHttpContent(content).Result |> shouldEqual "oh hi"
|
||||
Object.ReferenceEquals (Option.get observedContent, content) |> shouldEqual true
|
||||
|
||||
[<TestCase "ByteArr">]
|
||||
[<TestCase "ByteArr'">]
|
||||
[<TestCase "ByteArr''">]
|
||||
let ``Body param of byte arr`` (case : string) =
|
||||
let proc (message : HttpRequestMessage) : HttpResponseMessage Async =
|
||||
async {
|
||||
message.Method |> shouldEqual HttpMethod.Post
|
||||
let! content = message.Content.ReadAsStreamAsync () |> Async.AwaitTask
|
||||
let content = new StreamContent (content)
|
||||
let resp = new HttpResponseMessage (HttpStatusCode.OK)
|
||||
resp.Content <- content
|
||||
return resp
|
||||
}
|
||||
|
||||
use client = HttpClientMock.make (Uri "https://example.com") proc
|
||||
let api = PureGymApi.make client
|
||||
|
||||
let contents = [| 1uy ; 2uy ; 3uy ; 4uy |]
|
||||
|
||||
let observedContent =
|
||||
match case with
|
||||
| "ByteArr" -> api.CreateUserByteArr(contents).Result
|
||||
| "ByteArr'" -> api.CreateUserByteArr'(contents).Result
|
||||
| "ByteArr''" -> api.CreateUserByteArr''(contents).Result
|
||||
| _ -> failwith $"Unrecognised case: %s{case}"
|
||||
|
||||
let buf = Array.zeroCreate 10
|
||||
let written = observedContent.ReadAtLeast (buf.AsSpan (), 5, false)
|
||||
buf |> Array.take written |> shouldEqual contents
|
36
WoofWare.Myriad.Plugins.Test/TestHttpClient/TestPathParam.fs
Normal file
36
WoofWare.Myriad.Plugins.Test/TestHttpClient/TestPathParam.fs
Normal file
@@ -0,0 +1,36 @@
|
||||
namespace WoofWare.Myriad.Plugins.Test
|
||||
|
||||
open System
|
||||
open System.Net
|
||||
open System.Net.Http
|
||||
open NUnit.Framework
|
||||
open FsUnitTyped
|
||||
open PureGym
|
||||
|
||||
[<TestFixture>]
|
||||
module TestPathParam =
|
||||
|
||||
[<Test>]
|
||||
let ``Path params are escaped`` () =
|
||||
let proc (message : HttpRequestMessage) : HttpResponseMessage Async =
|
||||
async {
|
||||
message.Method |> shouldEqual HttpMethod.Get
|
||||
|
||||
let expectedUriPrefix = "https://example.com/endpoint/"
|
||||
|
||||
let actualUri = message.RequestUri.ToString ()
|
||||
|
||||
if not (actualUri.StartsWith (expectedUriPrefix, StringComparison.Ordinal)) then
|
||||
failwith $"wrong prefix on %s{actualUri}"
|
||||
|
||||
let content = new StringContent (actualUri.Substring expectedUriPrefix.Length)
|
||||
let resp = new HttpResponseMessage (HttpStatusCode.OK)
|
||||
resp.Content <- content
|
||||
return resp
|
||||
}
|
||||
|
||||
use client = HttpClientMock.make (Uri "https://example.com") proc
|
||||
let api = PureGymApi.make client
|
||||
|
||||
api.GetPathParam("hello/world?(hi)").Result
|
||||
|> shouldEqual "hello%2fworld%3f(hi)"
|
@@ -0,0 +1,238 @@
|
||||
namespace WoofWare.Myriad.Plugins.Test
|
||||
|
||||
open System
|
||||
open System.Net
|
||||
open System.Net.Http
|
||||
open NUnit.Framework
|
||||
open PureGym
|
||||
open FsUnitTyped
|
||||
|
||||
[<TestFixture>]
|
||||
module TestPureGymRestApi =
|
||||
// several of these, to check behaviour around treatment of initial slashes
|
||||
let baseUris =
|
||||
[
|
||||
// Everything is relative to the root:
|
||||
"https://example.com"
|
||||
// Everything is also relative to the root, because `foo` is not a subdir:
|
||||
"https://example.com/foo"
|
||||
// Everything is relative to `foo`, because `foo` is a subdir
|
||||
"https://example.com/foo/"
|
||||
]
|
||||
|> List.map Uri
|
||||
|
||||
let gymsCases =
|
||||
PureGymDtos.gymCases
|
||||
|> List.collect (fun (json, gym) -> [ $"[%s{json}]", [ gym ] ; $"[%s{json}, %s{json}]", [ gym ; gym ] ])
|
||||
|> List.allPairs baseUris
|
||||
|> List.map TestCaseData
|
||||
|
||||
[<TestCaseSource(nameof gymsCases)>]
|
||||
let ``Test GetGyms`` (baseUri : Uri, (json : string, expected : Gym list)) =
|
||||
let proc (message : HttpRequestMessage) : HttpResponseMessage Async =
|
||||
async {
|
||||
message.Method |> shouldEqual HttpMethod.Get
|
||||
|
||||
// URI is relative in the attribute on the IPureGymApi member,
|
||||
// so this never gets redirected
|
||||
let expectedUri =
|
||||
match baseUri.ToString () with
|
||||
| "https://example.com/" -> "https://example.com/v1/gyms/"
|
||||
| "https://example.com/foo" -> "https://example.com/v1/gyms/"
|
||||
| "https://example.com/foo/" -> "https://example.com/foo/v1/gyms/"
|
||||
| s -> failwith $"Unrecognised base URI: %s{s}"
|
||||
|
||||
message.RequestUri.ToString () |> shouldEqual expectedUri
|
||||
|
||||
let content = new StringContent (json)
|
||||
let resp = new HttpResponseMessage (HttpStatusCode.OK)
|
||||
resp.Content <- content
|
||||
return resp
|
||||
}
|
||||
|
||||
use client = HttpClientMock.make baseUri proc
|
||||
let api = PureGymApi.make client
|
||||
|
||||
api.GetGyms().Result |> shouldEqual expected
|
||||
|
||||
let gymAttendanceCases =
|
||||
PureGymDtos.gymAttendanceCases
|
||||
|> List.allPairs baseUris
|
||||
|> List.map TestCaseData
|
||||
|
||||
[<TestCaseSource(nameof gymAttendanceCases)>]
|
||||
let ``Test GetGymAttendance`` (baseUri : Uri, (json : string, expected : GymAttendance)) =
|
||||
let requestedGym = 3
|
||||
|
||||
let proc (message : HttpRequestMessage) : HttpResponseMessage Async =
|
||||
async {
|
||||
message.Method |> shouldEqual HttpMethod.Get
|
||||
|
||||
// URI is relative in the attribute on the IPureGymApi member,
|
||||
// so this never gets redirected
|
||||
let expectedUri =
|
||||
match baseUri.ToString () with
|
||||
| "https://example.com/" -> $"https://example.com/v1/gyms/%i{requestedGym}/attendance"
|
||||
| "https://example.com/foo" -> $"https://example.com/v1/gyms/%i{requestedGym}/attendance"
|
||||
| "https://example.com/foo/" -> $"https://example.com/foo/v1/gyms/%i{requestedGym}/attendance"
|
||||
| s -> failwith $"Unrecognised base URI: %s{s}"
|
||||
|
||||
message.RequestUri.ToString () |> shouldEqual expectedUri
|
||||
|
||||
let content = new StringContent (json)
|
||||
let resp = new HttpResponseMessage (HttpStatusCode.OK)
|
||||
resp.Content <- content
|
||||
return resp
|
||||
}
|
||||
|
||||
use client = HttpClientMock.make baseUri proc
|
||||
let api = PureGymApi.make client
|
||||
|
||||
api.GetGymAttendance(requestedGym).Result |> shouldEqual expected
|
||||
|
||||
let memberCases =
|
||||
PureGymDtos.memberCases |> List.allPairs baseUris |> List.map TestCaseData
|
||||
|
||||
[<TestCaseSource(nameof memberCases)>]
|
||||
let ``Test GetMember`` (baseUri : Uri, (json : string, expected : Member)) =
|
||||
let proc (message : HttpRequestMessage) : HttpResponseMessage Async =
|
||||
async {
|
||||
message.Method |> shouldEqual HttpMethod.Get
|
||||
|
||||
// URI is relative in the attribute on the IPureGymApi member,
|
||||
// so this never gets redirected
|
||||
let expectedUri =
|
||||
match baseUri.ToString () with
|
||||
| "https://example.com/" -> "https://example.com/v1/member"
|
||||
| "https://example.com/foo" -> "https://example.com/v1/member"
|
||||
| "https://example.com/foo/" -> "https://example.com/foo/v1/member"
|
||||
| s -> failwith $"Unrecognised base URI: %s{s}"
|
||||
|
||||
message.RequestUri.ToString () |> shouldEqual expectedUri
|
||||
|
||||
let content = new StringContent (json)
|
||||
let resp = new HttpResponseMessage (HttpStatusCode.OK)
|
||||
resp.Content <- content
|
||||
return resp
|
||||
}
|
||||
|
||||
use client = HttpClientMock.make baseUri proc
|
||||
let api = PureGymApi.make client
|
||||
|
||||
api.GetMember().Result |> shouldEqual expected
|
||||
|
||||
let gymCases =
|
||||
PureGymDtos.gymCases |> List.allPairs baseUris |> List.map TestCaseData
|
||||
|
||||
[<TestCaseSource(nameof gymCases)>]
|
||||
let ``Test GetGym`` (baseUri : Uri, (json : string, expected : Gym)) =
|
||||
let requestedGym = 3
|
||||
|
||||
let proc (message : HttpRequestMessage) : HttpResponseMessage Async =
|
||||
async {
|
||||
message.Method |> shouldEqual HttpMethod.Get
|
||||
|
||||
// URI is relative in the attribute on the IPureGymApi member,
|
||||
// so this never gets redirected
|
||||
let expectedUri =
|
||||
match baseUri.ToString () with
|
||||
| "https://example.com/" -> $"https://example.com/v1/gyms/%i{requestedGym}"
|
||||
| "https://example.com/foo" -> $"https://example.com/v1/gyms/%i{requestedGym}"
|
||||
| "https://example.com/foo/" -> $"https://example.com/foo/v1/gyms/%i{requestedGym}"
|
||||
| s -> failwith $"Unrecognised base URI: %s{s}"
|
||||
|
||||
message.RequestUri.ToString () |> shouldEqual expectedUri
|
||||
|
||||
let content = new StringContent (json)
|
||||
let resp = new HttpResponseMessage (HttpStatusCode.OK)
|
||||
resp.Content <- content
|
||||
return resp
|
||||
}
|
||||
|
||||
use client = HttpClientMock.make baseUri proc
|
||||
let api = PureGymApi.make client
|
||||
|
||||
api.GetGym(requestedGym).Result |> shouldEqual expected
|
||||
|
||||
let memberActivityCases =
|
||||
PureGymDtos.memberActivityDtoCases
|
||||
|> List.allPairs baseUris
|
||||
|> List.map TestCaseData
|
||||
|
||||
[<TestCaseSource(nameof memberActivityCases)>]
|
||||
let ``Test GetMemberActivity`` (baseUri : Uri, (json : string, expected : MemberActivityDto)) =
|
||||
let proc (message : HttpRequestMessage) : HttpResponseMessage Async =
|
||||
async {
|
||||
message.Method |> shouldEqual HttpMethod.Get
|
||||
|
||||
// URI is relative in the attribute on the IPureGymApi member,
|
||||
// so this never gets redirected
|
||||
let expectedUri =
|
||||
match baseUri.ToString () with
|
||||
| "https://example.com/" -> "https://example.com/v1/member/activity"
|
||||
| "https://example.com/foo" -> "https://example.com/v1/member/activity"
|
||||
| "https://example.com/foo/" -> "https://example.com/foo/v1/member/activity"
|
||||
| s -> failwith $"Unrecognised base URI: %s{s}"
|
||||
|
||||
message.RequestUri.ToString () |> shouldEqual expectedUri
|
||||
|
||||
let content = new StringContent (json)
|
||||
let resp = new HttpResponseMessage (HttpStatusCode.OK)
|
||||
resp.Content <- content
|
||||
return resp
|
||||
}
|
||||
|
||||
use client = HttpClientMock.make baseUri proc
|
||||
let api = PureGymApi.make client
|
||||
|
||||
api.GetMemberActivity().Result |> shouldEqual expected
|
||||
|
||||
let dates =
|
||||
[
|
||||
for month = 1 to 3 do
|
||||
// span the number 12, to catch muddling up month and day
|
||||
for day = 11 to 13 do
|
||||
yield DateOnly (2023, month, day)
|
||||
]
|
||||
|
||||
let sessionsCases =
|
||||
PureGymDtos.sessionsCases
|
||||
|> List.allPairs dates
|
||||
|> List.allPairs dates
|
||||
|> List.allPairs baseUris
|
||||
|> List.map TestCaseData
|
||||
|
||||
let inline dateOnlyToString (d : DateOnly) : string =
|
||||
let month = if d.Month < 10 then $"0%i{d.Month}" else $"%i{d.Month}"
|
||||
let day = if d.Day < 10 then $"0%i{d.Day}" else $"%i{d.Day}"
|
||||
$"{d.Year}-{month}-{day}"
|
||||
|
||||
[<TestCaseSource(nameof sessionsCases)>]
|
||||
let ``Test GetSessions``
|
||||
(
|
||||
baseUri : Uri,
|
||||
(startDate : DateOnly, (endDate : DateOnly, (json : string, expected : Sessions)))
|
||||
)
|
||||
=
|
||||
let proc (message : HttpRequestMessage) : HttpResponseMessage Async =
|
||||
async {
|
||||
message.Method |> shouldEqual HttpMethod.Get
|
||||
|
||||
// This one is specified as being absolute, in its attribute on the IPureGymApi type
|
||||
let expectedUri =
|
||||
let fromDate = dateOnlyToString startDate
|
||||
let toDate = dateOnlyToString endDate
|
||||
$"https://example.com/v2/gymSessions/member?fromDate=%s{fromDate}&toDate=%s{toDate}"
|
||||
|
||||
message.RequestUri.ToString () |> shouldEqual expectedUri
|
||||
|
||||
let content = new StringContent (json)
|
||||
let resp = new HttpResponseMessage (HttpStatusCode.OK)
|
||||
resp.Content <- content
|
||||
return resp
|
||||
}
|
||||
|
||||
use client = HttpClientMock.make baseUri proc
|
||||
let api = PureGymApi.make client
|
||||
|
||||
api.GetSessions(startDate, endDate).Result |> shouldEqual expected
|
@@ -0,0 +1,88 @@
|
||||
namespace WoofWare.Myriad.Plugins.Test
|
||||
|
||||
open System
|
||||
open System.IO
|
||||
open System.Net
|
||||
open FsUnitTyped
|
||||
open System.Net.Http
|
||||
open PureGym
|
||||
open NUnit.Framework
|
||||
|
||||
[<TestFixture>]
|
||||
module TestReturnTypes =
|
||||
|
||||
[<Test>]
|
||||
let ``String return`` () =
|
||||
let proc (message : HttpRequestMessage) : HttpResponseMessage Async =
|
||||
async {
|
||||
message.Method |> shouldEqual HttpMethod.Get
|
||||
let content = new StringContent ("this is not a JSON string")
|
||||
let resp = new HttpResponseMessage (HttpStatusCode.OK)
|
||||
resp.Content <- content
|
||||
return resp
|
||||
}
|
||||
|
||||
use client = HttpClientMock.make (Uri "https://example.com") proc
|
||||
let api = PureGymApi.make client
|
||||
|
||||
api.GetPathParam("hi").Result |> shouldEqual "this is not a JSON string"
|
||||
|
||||
[<TestCase "GetStream">]
|
||||
[<TestCase "GetStream'">]
|
||||
[<TestCase "GetStream''">]
|
||||
let ``Stream return`` (case : string) =
|
||||
let result = [| 1uy ; 2uy ; 3uy ; 4uy |]
|
||||
|
||||
let proc (message : HttpRequestMessage) : HttpResponseMessage Async =
|
||||
async {
|
||||
message.Method |> shouldEqual HttpMethod.Get
|
||||
let result = new MemoryStream (result)
|
||||
let content = new StreamContent (result)
|
||||
let resp = new HttpResponseMessage (HttpStatusCode.OK)
|
||||
resp.Content <- content
|
||||
return resp
|
||||
}
|
||||
|
||||
use client = HttpClientMock.make (Uri "https://example.com") proc
|
||||
let api = PureGymApi.make client
|
||||
|
||||
use stream =
|
||||
match case with
|
||||
| "GetStream" -> api.GetStream().Result
|
||||
| "GetStream'" -> api.GetStream'().Result
|
||||
| "GetStream''" -> api.GetStream''().Result
|
||||
| _ -> failwith $"unrecognised case: %s{case}"
|
||||
|
||||
let buf = Array.zeroCreate 10
|
||||
let written = stream.ReadAtLeast (buf.AsSpan (), 10, false)
|
||||
Array.take written buf |> shouldEqual result
|
||||
|
||||
[<TestCase "GetResponseMessage">]
|
||||
[<TestCase "GetResponseMessage'">]
|
||||
[<TestCase "GetResponseMessage''">]
|
||||
[<TestCase "GetResponseMessage'''">]
|
||||
let ``HttpResponseMessage return`` (case : string) =
|
||||
let mutable responseMessage = None
|
||||
|
||||
let proc (message : HttpRequestMessage) : HttpResponseMessage Async =
|
||||
async {
|
||||
message.Method |> shouldEqual HttpMethod.Get
|
||||
let content = new StringContent ("a response!")
|
||||
let resp = new HttpResponseMessage (HttpStatusCode.OK)
|
||||
resp.Content <- content
|
||||
responseMessage <- Some resp
|
||||
return resp
|
||||
}
|
||||
|
||||
use client = HttpClientMock.make (Uri "https://example.com") proc
|
||||
let api = PureGymApi.make client
|
||||
|
||||
let message =
|
||||
match case with
|
||||
| "GetResponseMessage" -> api.GetResponseMessage().Result
|
||||
| "GetResponseMessage'" -> api.GetResponseMessage'().Result
|
||||
| "GetResponseMessage''" -> api.GetResponseMessage''().Result
|
||||
| "GetResponseMessage'''" -> api.GetResponseMessage'''().Result
|
||||
| _ -> failwith $"unrecognised case: %s{case}"
|
||||
|
||||
Object.ReferenceEquals (message, Option.get responseMessage) |> shouldEqual true
|
34
WoofWare.Myriad.Plugins.Test/TestJsonParse/TestJsonParse.fs
Normal file
34
WoofWare.Myriad.Plugins.Test/TestJsonParse/TestJsonParse.fs
Normal file
@@ -0,0 +1,34 @@
|
||||
namespace WoofWare.Myriad.Plugins.Test
|
||||
|
||||
open System.Text.Json.Nodes
|
||||
open ConsumePlugin
|
||||
open NUnit.Framework
|
||||
open FsUnitTyped
|
||||
|
||||
[<TestFixture>]
|
||||
module TestJsonParse =
|
||||
[<Test>]
|
||||
let ``Single example`` () =
|
||||
let s =
|
||||
"""
|
||||
{
|
||||
"a": 3, "another-thing": "hello", "hi": [6, 1], "d": {"something": "oh hi"},
|
||||
"e": ["something", "else"], "f": []
|
||||
}
|
||||
"""
|
||||
|
||||
let expected =
|
||||
{
|
||||
A = 3
|
||||
B = "hello"
|
||||
C = [ 6 ; 1 ]
|
||||
D =
|
||||
{
|
||||
Thing = "oh hi"
|
||||
}
|
||||
E = [| "something" ; "else" |]
|
||||
F = [||]
|
||||
}
|
||||
|
||||
let actual = s |> JsonNode.Parse |> JsonRecordType.jsonParse
|
||||
actual |> shouldEqual expected
|
@@ -0,0 +1,71 @@
|
||||
namespace WoofWare.Myriad.Plugins.Test
|
||||
|
||||
open System
|
||||
open System.Text.Json.Nodes
|
||||
open NUnit.Framework
|
||||
open FsUnitTyped
|
||||
open PureGym
|
||||
|
||||
[<TestFixture>]
|
||||
module TestPureGymJson =
|
||||
|
||||
let gymOpeningHoursCases = PureGymDtos.gymOpeningHoursCases |> List.map TestCaseData
|
||||
|
||||
[<TestCaseSource(nameof gymOpeningHoursCases)>]
|
||||
let ``GymOpeningHours JSON parse`` (json : string, expected : GymOpeningHours) =
|
||||
JsonNode.Parse json |> GymOpeningHours.jsonParse |> shouldEqual expected
|
||||
|
||||
let gymAccessOptionsCases =
|
||||
PureGymDtos.gymAccessOptionsCases |> List.map TestCaseData
|
||||
|
||||
[<TestCaseSource(nameof gymAccessOptionsCases)>]
|
||||
let ``GymAccessOptions JSON parse`` (json : string, expected : GymAccessOptions) =
|
||||
JsonNode.Parse json |> GymAccessOptions.jsonParse |> shouldEqual expected
|
||||
|
||||
let gymLocationCases = PureGymDtos.gymLocationCases |> List.map TestCaseData
|
||||
|
||||
[<TestCaseSource(nameof gymLocationCases)>]
|
||||
let ``GymLocation JSON parse`` (json : string, expected : GymLocation) =
|
||||
JsonNode.Parse json |> GymLocation.jsonParse |> shouldEqual expected
|
||||
|
||||
let gymAddressCases = PureGymDtos.gymAddressCases |> List.map TestCaseData
|
||||
|
||||
[<TestCaseSource(nameof gymAddressCases)>]
|
||||
let ``GymAddress JSON parse`` (json : string, expected : GymAddress) =
|
||||
JsonNode.Parse (json, Nullable (JsonNodeOptions (PropertyNameCaseInsensitive = true)))
|
||||
|> GymAddress.jsonParse
|
||||
|> shouldEqual expected
|
||||
|
||||
let gymCases = PureGymDtos.gymCases |> List.map TestCaseData
|
||||
|
||||
[<TestCaseSource(nameof gymCases)>]
|
||||
let ``Gym JSON parse`` (json : string, expected : Gym) =
|
||||
JsonNode.Parse json |> Gym.jsonParse |> shouldEqual expected
|
||||
|
||||
let memberCases = PureGymDtos.memberCases |> List.map TestCaseData
|
||||
|
||||
[<TestCaseSource(nameof memberCases)>]
|
||||
let ``Member JSON parse`` (json : string, expected : Member) =
|
||||
json |> JsonNode.Parse |> Member.jsonParse |> shouldEqual expected
|
||||
|
||||
let gymAttendanceCases = PureGymDtos.gymAttendanceCases |> List.map TestCaseData
|
||||
|
||||
[<TestCaseSource(nameof gymAttendanceCases)>]
|
||||
let ``GymAttendance JSON parse`` (json : string, expected : GymAttendance) =
|
||||
json |> JsonNode.Parse |> GymAttendance.jsonParse |> shouldEqual expected
|
||||
|
||||
let memberActivityDtoCases =
|
||||
PureGymDtos.memberActivityDtoCases |> List.map TestCaseData
|
||||
|
||||
[<TestCaseSource(nameof memberActivityDtoCases)>]
|
||||
let ``MemberActivityDto JSON parse`` (json : string, expected : MemberActivityDto) =
|
||||
json |> JsonNode.Parse |> MemberActivityDto.jsonParse |> shouldEqual expected
|
||||
|
||||
let sessionsCases = PureGymDtos.sessionsCases |> List.map TestCaseData
|
||||
|
||||
[<TestCaseSource(nameof sessionsCases)>]
|
||||
let ``Sessions JSON parse`` (json : string, expected : Sessions) =
|
||||
json
|
||||
|> fun o -> JsonNode.Parse (o, Nullable (JsonNodeOptions (PropertyNameCaseInsensitive = true)))
|
||||
|> Sessions.jsonParse
|
||||
|> shouldEqual expected
|
24
WoofWare.Myriad.Plugins.Test/TestRemoveOptions.fs
Normal file
24
WoofWare.Myriad.Plugins.Test/TestRemoveOptions.fs
Normal file
@@ -0,0 +1,24 @@
|
||||
namespace WoofWare.Myriad.Plugins.Test
|
||||
|
||||
open FsCheck
|
||||
open ConsumePlugin
|
||||
open NUnit.Framework
|
||||
open FsUnitTyped
|
||||
|
||||
module TestRemoveOptions =
|
||||
|
||||
let shortenProperty (f : RecordType) =
|
||||
let g = RecordType.shorten f
|
||||
|
||||
g.B |> shouldEqual f.B
|
||||
g.C |> shouldEqual f.C
|
||||
|
||||
match f.A with
|
||||
| None -> g.A |> shouldEqual (RecordType.DefaultA ())
|
||||
| Some a -> g.A |> shouldEqual a
|
||||
|
||||
true
|
||||
|
||||
[<Test>]
|
||||
let ``shorten works`` () =
|
||||
Check.QuickThrowOnFailure shortenProperty
|
24
WoofWare.Myriad.Plugins.Test/TestSurface.fs
Normal file
24
WoofWare.Myriad.Plugins.Test/TestSurface.fs
Normal file
@@ -0,0 +1,24 @@
|
||||
namespace WoofWare.Myriad.Plugins.Test
|
||||
|
||||
open NUnit.Framework
|
||||
open WoofWare.Myriad.Plugins
|
||||
open ApiSurface
|
||||
|
||||
[<TestFixture>]
|
||||
module TestSurface =
|
||||
let assembly = typeof<RemoveOptionsAttribute>.Assembly
|
||||
|
||||
[<Test>]
|
||||
let ``Ensure API surface has not been modified`` () = ApiSurface.assertIdentical assembly
|
||||
|
||||
[<Test>]
|
||||
let ``Check version against remote`` () =
|
||||
MonotonicVersion.validate assembly "WoofWare.Myriad.Plugins"
|
||||
|
||||
[<Test ; Explicit>]
|
||||
let ``Update API surface`` () =
|
||||
ApiSurface.writeAssemblyBaseline assembly
|
||||
|
||||
[<Test>]
|
||||
let ``Ensure public API is fully documented`` () =
|
||||
DocCoverage.assertFullyDocumented assembly
|
@@ -0,0 +1,40 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<IsPackable>false</IsPackable>
|
||||
<IsTestProject>true</IsTestProject>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="HttpClient.fs"/>
|
||||
<Compile Include="PureGymDtos.fs"/>
|
||||
<Compile Include="TestJsonParse\TestJsonParse.fs" />
|
||||
<Compile Include="TestJsonParse\TestPureGymJson.fs" />
|
||||
<Compile Include="TestHttpClient\TestPureGymRestApi.fs" />
|
||||
<Compile Include="TestHttpClient\TestPathParam.fs" />
|
||||
<Compile Include="TestHttpClient\TestReturnTypes.fs" />
|
||||
<Compile Include="TestHttpClient\TestAllowAnyStatusCode.fs" />
|
||||
<Compile Include="TestHttpClient\TestBasePath.fs" />
|
||||
<Compile Include="TestHttpClient\TestBodyParam.fs" />
|
||||
<Compile Include="TestSurface.fs"/>
|
||||
<Compile Include="TestRemoveOptions.fs"/>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="ApiSurface" Version="4.0.25"/>
|
||||
<PackageReference Include="FsCheck" Version="2.16.6"/>
|
||||
<PackageReference Include="FsUnit" Version="6.0.0-alpha3"/>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0"/>
|
||||
<PackageReference Include="NUnit" Version="4.0.1"/>
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0"/>
|
||||
<PackageReference Include="NUnit.Analyzers" Version="3.10.0"/>
|
||||
<PackageReference Include="coverlet.collector" Version="6.0.0"/>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\WoofWare.Myriad.Plugins\WoofWare.Myriad.Plugins.fsproj"/>
|
||||
<ProjectReference Include="..\ConsumePlugin\ConsumePlugin.fsproj"/>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
Reference in New Issue
Block a user