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;
}
|