summaryrefslogtreecommitdiffstats
path: root/tests/Cepis.Tests/BatchTests.cs
blob: 8e075f139decbcd1b1936078ef58f50b6dada7b2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
using System.Text;

namespace Cepis.Tests;

/// <summary>The batch: order, absences, chunking, and the missing coordinate.</summary>
public sealed class BatchTests : HttpTestBase
{
    [Fact]
    public async Task KeepsTheRequestedOrderAndLength()
    {
        Server.Handle(_ => Reply.Of(200, Fixtures.CsvBatch));

        var result = await Client.LookupManyAsync(["01001000", "99999999", "20040020"]);

        Assert.Equal(3, result.Count);
        Assert.Equal("São Paulo", result[0]?.Localidade);
        Assert.Null(result[1]);
        Assert.Equal("Rio de Janeiro", result[2]?.Localidade);
    }

    [Fact]
    public async Task CarriesNoCoordinate()
    {
        Server.Handle(_ => Reply.Of(200, Fixtures.CsvBatch));

        var result = await Client.LookupManyAsync(["01001000"]);

        Assert.NotNull(result[0]);
        Assert.Null(result[0]!.Geo);
    }

    [Fact]
    public async Task AMalformedCepIsNullRatherThanAnError()
    {
        Server.Handle(call => Reply.Of(200, Csv(call)));

        var result = await Client.LookupManyAsync(["01001000", "oops", "20040020"]);

        Assert.Equal(3, result.Count);
        Assert.NotNull(result[0]);
        Assert.Null(result[1]);
        Assert.NotNull(result[2]);
    }

    [Fact]
    public async Task ChunksAboveFiveHundred()
    {
        Server.Handle(call => Reply.Of(200, Csv(call)));
        var ceps = Enumerable.Range(0, 600).Select(i => $"{i:D8}").ToList();

        var result = await Client.LookupManyAsync(ceps);

        Assert.Equal(600, result.Count);
        Assert.Equal(2, Server.Calls.Count);
        Assert.Equal(CepisClient.MaxBatch, CountCeps(Server.Calls[0]));
        Assert.Equal(100, CountCeps(Server.Calls[1]));
        Assert.All(result, address => Assert.NotNull(address));
    }

    [Fact]
    public async Task ExactlyFiveHundredIsOneRequest()
    {
        Server.Handle(call => Reply.Of(200, Csv(call)));
        var ceps = Enumerable.Range(0, CepisClient.MaxBatch).Select(i => $"{i:D8}").ToList();

        var result = await Client.LookupManyAsync(ceps);

        Assert.Equal(CepisClient.MaxBatch, result.Count);
        Assert.Single(Server.Calls);
    }

    [Fact]
    public async Task AShortResponseIsPaddedRatherThanShifted()
    {
        Server.Handle(_ => Reply.Of(200, Fixtures.CsvHeader + "\n" + Fixtures.CsvRow("01001000") + "\n"));

        var result = await Client.LookupManyAsync(["01001000", "20040020", "30140071"]);

        Assert.Equal(3, result.Count);
        Assert.Equal("01001000", result[0]?.Cep);
        Assert.Null(result[1]);
        Assert.Null(result[2]);
    }

    [Fact]
    public async Task AnEmptyInputMakesNoRequest()
    {
        var result = await Client.LookupManyAsync([]);

        Assert.Empty(result);
        Assert.Empty(Server.Calls);
    }

    [Fact]
    public async Task ValuesWithCommasSurviveTheParse()
    {
        Server.Handle(_ => Reply.Of(200, Fixtures.CsvHeader + "\n"
            + "\"01001000\",\"Praça da Sé, lado ímpar\",,,Sé,São Paulo,SP,São Paulo,Sudeste,3550308,1004,11,7107\n"));

        var result = await Client.LookupManyAsync(["01001000"]);

        Assert.Equal("Praça da Sé, lado ímpar", result[0]?.Logradouro);
    }

    private static string Csv(Call call)
    {
        var body = new StringBuilder(Fixtures.CsvHeader);
        foreach (var cep in Requested(call))
        {
            body.Append('\n').Append(cep.Length == 8 ? Fixtures.CsvRow(cep) : cep + ",,,,,,,,,,,,");
        }

        return body.Append('\n').ToString();
    }

    private static string[] Requested(Call call) =>
        (call.Ceps ?? "").Split(',', StringSplitOptions.RemoveEmptyEntries);

    private static int CountCeps(Call call) => Requested(call).Length;
}