#include #include #include "ApiBatch.hpp" #include "net/FakeApiCall.hpp" using namespace geopro::net; using geopro::net::test::FakeApiCall; namespace { ApiResponse ok(int code = 200) { ApiResponse r; r.code = code; r.httpStatus = 200; return r; } ApiResponse bad() { ApiResponse r; r.code = 500; r.httpStatus = 200; r.msg = QStringLiteral("boom"); return r; } // repo 注入的失败谓词:业务码 != 200 或传输错误。 auto isFailure = [](const ApiResponse& r) { return r.code != 200 || !r.rawError.isEmpty(); }; } TEST(ApiBatch, SucceedsWhenAllOk) { auto* a = new FakeApiCall; auto* b = new FakeApiCall; auto* batch = new ApiBatch({a, b}, isFailure); QSignalSpy okSpy(batch, &ApiBatch::succeeded); QSignalSpy failSpy(batch, &ApiBatch::failed); a->fire(ok()); EXPECT_EQ(okSpy.count(), 0); // 还差 b b->fire(ok()); EXPECT_EQ(okSpy.count(), 1); // 全到齐 EXPECT_EQ(failSpy.count(), 0); } TEST(ApiBatch, FailFastAbortsOthers) { auto* a = new FakeApiCall; auto* b = new FakeApiCall; // 慢的(永不 fire) auto* batch = new ApiBatch({a, b}, isFailure); QSignalSpy failSpy(batch, &ApiBatch::failed); QSignalSpy okSpy(batch, &ApiBatch::succeeded); a->fire(bad()); // 首个失败 EXPECT_EQ(failSpy.count(), 1); EXPECT_EQ(okSpy.count(), 0); EXPECT_TRUE(b->aborted); // 其余在飞被 abort } TEST(ApiBatch, AbortGateSuppressesLateSignals) { auto* a = new FakeApiCall; auto* b = new FakeApiCall; auto* batch = new ApiBatch({a, b}, isFailure); QSignalSpy okSpy(batch, &ApiBatch::succeeded); QSignalSpy failSpy(batch, &ApiBatch::failed); batch->abort(); EXPECT_TRUE(a->aborted); EXPECT_TRUE(b->aborted); a->fire(ok()); // 迟到信号 b->fire(ok()); EXPECT_EQ(okSpy.count(), 0); // aborted_ 闸门:不 emit EXPECT_EQ(failSpy.count(), 0); }