1+ #include < gmock/gmock.h>
2+ #include < rest/configuration.h>
3+ #include < rest/controller/MeterReadingController.h>
4+
5+ #include < boost/beast/http.hpp>
6+ #include < nlohmann/json.hpp>
7+
8+ using nlohmann::json;
9+ using ::testing::Eq;
10+
11+ namespace http = boost::beast::http;
12+
13+ class MeterReadingControllerTest : public ::testing::Test {
14+ protected:
15+ std::unordered_map<std::string, std::vector<ElectricityReading>> meterAssociatedReadings;
16+ ElectricityReadingService electricityReadingService{meterAssociatedReadings};
17+ MeterReadingService meterReadingService{meterAssociatedReadings};
18+ MeterReadingController controller{electricityReadingService, meterReadingService};
19+
20+ http::request<http::string_body> BuildRequest (http::verb verb, boost::string_view target, const json &request_body) {
21+ http::request<http::string_body> req{http::verb::post , " /readings/store" , 11 };
22+ req.set (http::field::content_type, " application/json" );
23+ req.body () = request_body.dump ();
24+ req.prepare_payload ();
25+ return req;
26+ }
27+ };
28+
29+ TEST_F (MeterReadingControllerTest, StoreShouldResponseWithErrorGivenNoMeterIdIsSupplied) {
30+ auto req = BuildRequest (http::verb::post , " /readings/store" , R"( {})" _json);
31+ std::vector<std::string> queries;
32+
33+ auto response = controller.Store (req, queries);
34+
35+ EXPECT_THAT (response.result (), Eq (http::status::internal_server_error));
36+ }
37+
38+ TEST_F (MeterReadingControllerTest, StoreShouldResponseWithErrorGivenEmptyMeterReading) {
39+ json body = R"( {
40+ "smartMeterId": "smart-meter-0",
41+ "electricityReadings": []
42+ })" _json;
43+ auto req = BuildRequest (http::verb::post , " /readings/store" , body);
44+ std::vector<std::string> queries;
45+
46+ auto response = controller.Store (req, queries);
47+
48+ EXPECT_THAT (response.result (), Eq (http::status::internal_server_error));
49+ }
50+
51+ TEST_F (MeterReadingControllerTest, StoreShouldResponseWithErrorGivenNoMeterReadingIsSupplied) {
52+ json body = R"( {
53+ "smartMeterId": "smart-meter-0"
54+ })" _json;
55+ auto req = BuildRequest (http::verb::post , " /readings/store" , body);
56+ std::vector<std::string> queries;
57+
58+ auto response = controller.Store (req, queries);
59+
60+ EXPECT_THAT (response.result (), Eq (http::status::internal_server_error));
61+ }
62+
63+ TEST_F (MeterReadingControllerTest, StoreShouldStoreGivenMultipleBatchesOfMeterReadings) {
64+ json body1 = R"( {
65+ "smartMeterId": "smart-meter-0",
66+ "electricityReadings": [
67+ {
68+ "time": "2021-08-18T06:42:15.725202Z",
69+ "reading": 1
70+ }
71+ ]
72+ })" _json;
73+ json body2 = R"( {
74+ "smartMeterId": "smart-meter-0",
75+ "electricityReadings": [
76+ {
77+ "time": "2021-08-18T06:44:15.725202Z",
78+ "reading": 2
79+ }
80+ ]
81+ })" _json;
82+ auto req1 = BuildRequest (http::verb::post , " /readings/store" , body1);
83+ auto req2 = BuildRequest (http::verb::post , " /readings/store" , body2);
84+ std::vector<std::string> queries;
85+
86+ controller.Store (req1, queries);
87+ controller.Store (req2, queries);
88+
89+ std::vector<ElectricityReading> expectedElectricityReadings = {
90+ {detail::fromRfc3339 (" 2021-08-18T06:42:15.725202Z" ), 1 },
91+ {detail::fromRfc3339 (" 2021-08-18T06:44:15.725202Z" ), 2 }
92+ };
93+
94+ EXPECT_THAT (meterReadingService.getReadings (" smart-meter-0" ), Eq (expectedElectricityReadings));
95+ }
96+
97+ TEST_F (MeterReadingControllerTest, StoreShouldStoreAssociatedWithUserGivenMeterReadingsAssociatedWithTheUser) {
98+ json body1 = R"( {
99+ "smartMeterId": "smart-meter-0",
100+ "electricityReadings": [
101+ {
102+ "time": "2021-08-18T06:42:15.725202Z",
103+ "reading": 1
104+ }
105+ ]
106+ })" _json;
107+ json body2 = R"( {
108+ "smartMeterId": "smart-meter-1",
109+ "electricityReadings": [
110+ {
111+ "time": "2021-08-18T06:44:15.725202Z",
112+ "reading": 2
113+ }
114+ ]
115+ })" _json;
116+ auto req1 = BuildRequest (http::verb::post , " /readings/store" , body1);
117+ auto req2 = BuildRequest (http::verb::post , " /readings/store" , body2);
118+ std::vector<std::string> queries;
119+
120+ controller.Store (req1, queries);
121+ controller.Store (req2, queries);
122+
123+ std::vector<ElectricityReading> expectedElectricityReadings = {
124+ {detail::fromRfc3339 (" 2021-08-18T06:42:15.725202Z" ), 1 },
125+ };
126+
127+ EXPECT_THAT (meterReadingService.getReadings (" smart-meter-0" ), Eq (expectedElectricityReadings));
128+ }
129+
130+ TEST_F (MeterReadingControllerTest, ReadShouldReturnNotFoundGivenMeterIdThatIsNotRecognised) {
131+ auto req = BuildRequest (http::verb::post , " /readings/store" , R"( {})" _json);
132+ std::vector<std::string> queries = {" smart-meter-0" };
133+
134+ auto response = controller.Read (req, queries);
135+
136+ EXPECT_THAT (response.result (), Eq (http::status::not_found));
137+ }
0 commit comments