 while everyone back home is enjoying summer Fridays and soaking up the warm summer sun. Needless to say, it’s been pretty hard to focus at work. (Especially with all the clouds and rain we’ve had lately.) SOOO, if you haven’t already, be sure to go check out her post and spread the love! Thanks for linking up with us Candace!?
What a great hike! You all look like you had so much fun together. I love a good hike, as long as it’s not too crazy-difficult.
Ok, when can I go?! This hike looks GORGEOUS! And I’m with you. Two months without getting up into those mountains would feel like forever to me too.
Lucky you having that on your doorstep!
Yay, I need to add this to my list! I actually haven’t heard of this one 🙂 Thanks for sharing!
I better get myself in a bit better shape for the steep parts. one way up and down I can handle. We are headed to Santiago later in the year. I can’t wait.
I love seeing you on video! You’re too cute and you and your friends seem really fun! I love when there are nice nature spots to escape to from the city. This definitely looks like a hike I can do, even though I’m in terrible physical shape!NCHELENGE - Barefoot and wearing long skirts, Congolese teenage girls dart across the sandy pitch, skilfully tackling each other for the football. Yet they fail to beat goalkeeper, Jilie, 17. “Even the boys want me on their team,” Jilie says smiling during the post-match celebrations. It’s like they have just won a major championship.
Jilie says she loves football and the other activities at the child-friendly space at the refugee transit centre in Zambia. But Jilie also wants to return school, so she can follow her dream to become a doctor.
“I’ve always wanted to be a doctor so I can make people well,” says Jilie, again with a smile. “My parents fell sick and died when I was young and so my brother brought me up,” she says with no trace of self-pity. “I had to drop out of school for three years as we had no money for school fees.” At the time, her brother Kaimba who was able to earn some money, financed her education. Jilie explains that he moved out to a town to become a priest. “My neighbours had a phone, so he would phone them and I could speak to him and he would tell me when he had put money in the bank for me to collect for my studies.” Jilie says she had a small plot of land which she farmed and had her own latrine, but had to fetch water from the lake.
Yet her life and her studies were disrupted when fighting broke out in her village. “They were killing people even in their sleep, so I fled with my neighbours.
Jilie plays in goal during a football match.
Jilie has been at the camp in Zambia for three months. She walks to her small tent which is near the child-friendly space. Inside the tent there is a reed mat that she sleeps on, and she has a few pots and clothes piled in one corner. A woman greets her as she cooks nshima (pounded maize) and soya beans in a pot over firewood. “When I feel lonely, I go and eat with the friends I have made here,” she says. One of her neighbours has neatly done her hair into tiny braids.
Soon Jilie, like the other around 15,000 refugees in Nchelenge, will move to Mantapala resettlement camp where she will have the opportunity to study. It will mean switching from French to English, although fortunately on both sides of the border they speak the same local language, Bemba. The Government of Zambia has already trained 28 Congolese and 14 Zambian teachers. UNICEF has supported the construction of 24 classrooms as well as latrines with washing facilities.
module Tests.Common

open System
open System.Collections.Generic
open System.IO
open System.Net.Http
open System.Net
open System.Net.Http.Headers
open System.Text
open System.Text.Json
open System.Threading
open System.Threading.Tasks

open FSharp.Control.Tasks

open Oryx
open Oryx.SystemTextJson.ResponseReader
open Microsoft.Extensions.Logging

type StringableContent (content: string) =
    inherit StringContent (content)
    override this.ToString() = content

type PushStreamContent (content: string) =
    inherit HttpContent ()
    let _content = content
    let mutable _disposed = false
    do base.Headers.ContentType <- MediaTypeHeaderValue "application/json"

    override this.ToString() = content

    override this.SerializeToStreamAsync(stream: Stream, context: TransportContext) : Task =
        task {
            let bytes = Encoding.ASCII.GetBytes(_content)
            do! stream.AsyncWrite(bytes)
            do! stream.FlushAsync()
        }
        :> _

    override this.TryComputeLength(length: byref<int64>) : bool =
        length <- -1L
        false

    override this.Dispose(disposing) =
        if _disposed then
            failwith "Already disposed!"
            ()

        base.Dispose(disposing)
        _disposed <- true

type HttpMessageHandlerStub (OnNextAsync: Func<HttpRequestMessage, CancellationToken, Task<HttpResponseMessage>>) =
    inherit HttpMessageHandler ()

    override self.SendAsync
        (
            request: HttpRequestMessage,
            cancellationToken: CancellationToken
        ) : Task<HttpResponseMessage> =
        task { return! OnNextAsync.Invoke(request, cancellationToken) }

let add (a: int) (b: int) = singleton (a + b)

exception TestException of code: int * message: string with
    override this.ToString() = this.message

let error msg : IHttpHandler<'TSource, 'TResult> = throw <| TestException(code = 400, message = msg)

/// A bad request handler to use with the `catch` handler. It takes a response to return as Ok.
let badRequestHandler<'TSource> (response: 'TSource) (error: exn) : IHttpHandler<'TSource> =
    { new IHttpHandler<'TSource> with
        member _.Subscribe(next) =
            { new IHttpNext<'TSource> with
                member _.OnNextAsync(ctx, _) =
                    task {
                        match error with
                        | :? TestException as ex ->
                            match enum<HttpStatusCode> (ex.code) with
                            | HttpStatusCode.BadRequest -> return! next.OnNextAsync(ctx, response)

                            | _ -> return! next.OnErrorAsync(ctx, error)
                        | _ -> return! next.OnErrorAsync(ctx, error)
                    }

                member _.OnErrorAsync(ctx, exn) = next.OnErrorAsync(ctx, exn)
                member _.OnCompletedAsync(ctx) = next.OnCompletedAsync(ctx) } }


let shouldRetry (error: exn) : bool =
    match error with
    | :? TestException -> true
    | _ -> false

let errorHandler (response: HttpResponse) (content: HttpContent option) =
    task { return TestException(code = int response.StatusCode, message = "Got error") }

let options = JsonSerializerOptions()

let get () =
    GET
    >=> withUrl "http://test.org"
    >=> withQuery [ struct ("debug", "true") ]
    >=> fetch
    >=> withError errorHandler
    >=> json options
    >=> log

let post content =
    POST
    >=> withResponseType JsonValue
    >=> withContent content
    >=> withCompletion HttpCompletionOption.ResponseHeadersRead
    >=> fetch
    >=> withError errorHandler
    >=> json options
    >=> log

//let retryCount = 5
//let retry next ctx = retry shouldRetry 500<ms> retryCount next ctx

type TestLogger<'a> () =
    member val Output: string = String.Empty with get, set
    member val LoggerLevel: LogLevel = LogLevel.Information with get, set

    member this.Log(logLevel: LogLevel, message: string) =
        this.Output <- this.Output + message
        this.LoggerLevel <- logLevel

    interface IDisposable with
        member this.Dispose() = ()

    interface ILogger<'a> with
        member this.Log<'TState>
            (
                logLevel: LogLevel,
                eventId: EventId,
                state: 'TState,
                exception': exn,
                formatter