@@ -16,6 +16,7 @@ open Microsoft.AspNetCore.Builder
1616open Microsoft.AspNetCore .Hosting
1717open Microsoft.AspNetCore .Http
1818open Microsoft.AspNetCore .TestHost
19+ open Microsoft.Extensions .DependencyInjection
1920
2021open Expecto
2122
@@ -24,6 +25,10 @@ open FSharpPlus.AspNetCore.Suave
2425open Notes
2526
2627module ` `integration test using test server`` =
28+ let tryParseInt ( s : string ) =
29+ match Int32.TryParse s with
30+ | true , n -> Some n
31+ | _ -> None
2732 module TestServer =
2833 let fakeDb () =
2934 let withUserId userId = (=) userId << fst
@@ -124,3 +129,51 @@ module ``integration test using test server`` =
124129 Expect.equal ( parseJson noteJson) ( Ok { id= NoteId 1 ; text= " my next text" }) " Expected note json"
125130 })
126131 ]
132+
133+ [<Tests>]
134+ let ``session state uses cookie`` =
135+ testCase " counter is incremented across requests with same cookie" <| fun _ -> waitFor( task {
136+ let sessionWebPart =
137+ Filters.path " /session"
138+ >=> Filters.statefulForSession
139+ >=> ( fun ctx ->
140+ match FSharpPlus.AspNetCore.Suave.HttpContext.state ctx with
141+ | Some store ->
142+ let current =
143+ store
144+ |> FSharpPlus.AspNetCore.Suave.Session.tryGet " counter"
145+ |> Option.bind tryParseInt
146+ |> Option.defaultValue 0
147+ store |> FSharpPlus.AspNetCore.Suave.Session.set " counter" ( string ( current + 1 ))
148+ Successful.OK ( sprintf " Hello %d time(s)" ( current + 1 )) ctx
149+ | None ->
150+ Successful.OK " No session available" ctx)
151+
152+ let builder =
153+ WebHostBuilder()
154+ .ConfigureServices( fun services ->
155+ services.AddDistributedMemoryCache() |> ignore
156+ services.AddSession() |> ignore)
157+ .Configure( fun app ->
158+ app.UseSession() |> ignore
159+ Suave.appRun sessionWebPart app |> ignore)
160+
161+ use testServer = new TestServer( builder)
162+ use client = testServer.CreateClient()
163+
164+ let! first = client.GetAsync( " http://localhost/session" )
165+ let! firstContent = first.Content.ReadAsStringAsync()
166+ let cookieHeader =
167+ first.Headers.GetValues( " Set-Cookie" )
168+ |> Seq.choose ( fun cookie -> cookie.Split( ';' ) |> Array.tryHead)
169+ |> String.concat " ; "
170+
171+ let request = new HttpRequestMessage( HttpMethod.Get, " http://localhost/session" )
172+ request.Headers.Add( " Cookie" , cookieHeader)
173+
174+ let! second = client.SendAsync( request)
175+ let! secondContent = second.Content.ReadAsStringAsync()
176+
177+ Expect.equal firstContent " Hello 1 time(s)" " Expected first session response"
178+ Expect.equal secondContent " Hello 2 time(s)" " Expected second session response"
179+ })
0 commit comments