From cc3071a28fb76f5e0a171c39b6b68b5426c41210 Mon Sep 17 00:00:00 2001 From: "Zachary J. Fields" Date: Fri, 8 Sep 2023 05:12:00 +0000 Subject: [PATCH] chore: rename binary RX API --- n_helpers.c | 15 +- note.h | 5 +- test/CMakeLists.txt | 2 +- test/src/NoteBinaryReceiveAll_test.cpp | 124 +++++++++++++ test/src/NoteBinaryReceiveRange_test.cpp | 224 ----------------------- test/src/NoteBinaryReceive_test.cpp | 220 ++++++++++++++++------ 6 files changed, 294 insertions(+), 296 deletions(-) create mode 100644 test/src/NoteBinaryReceiveAll_test.cpp delete mode 100644 test/src/NoteBinaryReceiveRange_test.cpp diff --git a/n_helpers.c b/n_helpers.c index 65f6d788..07d14bd5 100644 --- a/n_helpers.c +++ b/n_helpers.c @@ -342,7 +342,7 @@ uint32_t NoteBinaryMaxEncodedLength(uint32_t unencodedLength) //**************************************************************************/ /*! - @brief Receive a large binary object from the Notecard's binary buffer + @brief Receive the Notecard's entire binary buffer @param buffer A buffer to hold the binary object @param bufLen The total length of the provided buffer @@ -357,8 +357,8 @@ uint32_t NoteBinaryMaxEncodedLength(uint32_t unencodedLength) `NoteBinaryDataEncodedLength()`. */ /**************************************************************************/ -const char * NoteBinaryReceive(uint8_t *buffer, uint32_t bufLen, - uint32_t *dataLen) +const char * NoteBinaryReceiveAll(uint8_t *buffer, uint32_t bufLen, + uint32_t *dataLen) { const char *err = NULL; uint32_t decodedLen = 0; @@ -376,7 +376,7 @@ const char * NoteBinaryReceive(uint8_t *buffer, uint32_t bufLen, decodedLen = 0; } // Request entire binary data store from Notecard - else if ((err = NoteBinaryReceiveRange(buffer, bufLen, 0, decodedLen))) { + else if ((err = NoteBinaryReceive(buffer, bufLen, 0, decodedLen))) { decodedLen = 0; } @@ -389,7 +389,7 @@ const char * NoteBinaryReceive(uint8_t *buffer, uint32_t bufLen, //**************************************************************************/ /*! - @brief Receive a large binary range from the Notecard's binary buffer + @brief Receive a large binary object from the Notecard's binary buffer @param buffer A buffer to hold the binary range @param bufLen The total length of the provided buffer @@ -407,9 +407,8 @@ const char * NoteBinaryReceive(uint8_t *buffer, uint32_t bufLen, entire buffer use `NoteBinaryDataEncodedLength()` instead. */ /**************************************************************************/ -const char * NoteBinaryReceiveRange(uint8_t *buffer, uint32_t bufLen, - uint32_t decodedOffset, - uint32_t decodedLen) +const char * NoteBinaryReceive(uint8_t *buffer, uint32_t bufLen, + uint32_t decodedOffset, uint32_t decodedLen) { // Validate parameter(s) if (!buffer) { diff --git a/note.h b/note.h index 0e1c9192..30be9abf 100644 --- a/note.h +++ b/note.h @@ -329,10 +329,9 @@ const char * NoteBinaryEncode(const uint8_t *inBuf, uint32_t inLen, uint32_t NoteBinaryMaxDecodedLength(uint32_t bufferSize); uint32_t NoteBinaryMaxEncodedLength(uint32_t unencodedLength); const char * NoteBinaryReceive(uint8_t *buffer, uint32_t bufLen, + uint32_t decodedOffset, uint32_t decodedLen); +const char * NoteBinaryReceiveAll(uint8_t *buffer, uint32_t bufLen, uint32_t *dataLen); -const char * NoteBinaryReceiveRange(uint8_t *buffer, uint32_t bufLen, - uint32_t decodedOffset, - uint32_t decodedLen); const char * NoteBinaryTransmit(uint8_t *unencodedData, uint32_t unencodedLen, uint32_t bufLen, uint32_t notecardOffset); uint32_t NoteSetSTSecs(uint32_t secs); diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index f3e6023b..9856a120 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -156,7 +156,7 @@ add_test(NoteBinaryEncode_test) add_test(NoteBinaryMaxEncodedLength_test) add_test(NoteBinaryMaxDecodedLength_test) add_test(NoteBinaryReceive_test) -add_test(NoteBinaryReceiveRange_test) +add_test(NoteBinaryReceiveAll_test) add_test(NoteBinaryTransmit_test) if(NOTE_C_COVERAGE) diff --git a/test/src/NoteBinaryReceiveAll_test.cpp b/test/src/NoteBinaryReceiveAll_test.cpp new file mode 100644 index 00000000..c0778299 --- /dev/null +++ b/test/src/NoteBinaryReceiveAll_test.cpp @@ -0,0 +1,124 @@ +/*! + * @file NoteBinaryReceiveAll_test.cpp + * + * Written by the Blues Inc. team. + * + * Copyright (c) 2023 Blues Inc. MIT License. Use of this source code is + * governed by licenses granted by the copyright holder including that found in + * the + * LICENSE + * file. + * + */ + +#ifdef NOTE_C_TEST + +#include +#include "fff.h" + +#include "n_lib.h" + +DEFINE_FFF_GLOBALS +FAKE_VALUE_FUNC(const char *, NoteBinaryDataDecodedLength, uint32_t *) +FAKE_VALUE_FUNC(const char *, NoteBinaryReceive, uint8_t *, uint32_t, uint32_t, uint32_t) + +uint8_t buffer[12]; +const uint32_t bufLen = sizeof(buffer); +uint32_t dataLen = 0; + +namespace +{ + +SCENARIO("NoteBinaryReceiveAll") +{ + RESET_FAKE(NoteBinaryDataDecodedLength); + RESET_FAKE(NoteBinaryReceive); + dataLen = 17; + + GIVEN("Bad parameters are supplied") { + WHEN("buffer is NULL") { + const char *err = NoteBinaryReceiveAll(NULL, bufLen, &dataLen); + + THEN("An error is returned") { + CHECK(err != NULL); + } + } + WHEN("dataLen is NULL") { + const char *err = NoteBinaryReceiveAll(buffer, bufLen, NULL); + + THEN("An error is returned") { + CHECK(err != NULL); + } + } + } + + GIVEN("NoteBinaryDataDecodedLength() is invoked") { + WHEN("An error is encountered") { + const char *errMsg = "ERROR! Hacking too much time!"; + NoteBinaryDataDecodedLength_fake.return_val = errMsg; + const char *err = NoteBinaryReceiveAll(buffer, bufLen, &dataLen); + + REQUIRE(NoteBinaryDataDecodedLength_fake.call_count > 0); + THEN("NoteBinaryReceive() is not invoked") { + CHECK(NoteBinaryReceive_fake.call_count == 0); + } + THEN("The dataLen is set to zero") { + CHECK(dataLen == 0); + } + THEN("The error is returned") { + CHECK(!strcmp(err,errMsg)); + } + } + WHEN("No error is encountered") { + const uint32_t DECODED_LEN = 79; + NoteBinaryDataDecodedLength_fake.custom_fake = [](uint32_t *len) -> const char * { + *len = DECODED_LEN; + return NULL; + }; + const char *err = NoteBinaryReceiveAll(buffer, bufLen, &dataLen); + + REQUIRE(NoteBinaryDataDecodedLength_fake.call_count > 0); + THEN("NoteBinaryReceive() is invoked") { + CHECK(NoteBinaryReceive_fake.call_count > 0); + } + THEN("The decoded length is passed to NoteBinaryReceive()") { + CHECK(NoteBinaryReceive_fake.arg3_history[0] == DECODED_LEN); + } + } + } + GIVEN("NoteBinaryReceive() is invoked") { + const uint32_t DECODED_LEN = 79; + NoteBinaryDataDecodedLength_fake.custom_fake = [](uint32_t *len) -> const char * { + *len = DECODED_LEN; + return NULL; + }; + WHEN("An error is encountered") { + const char *errMsg = "ERROR! Hacking too much time!"; + NoteBinaryReceive_fake.return_val = errMsg; + const char *err = NoteBinaryReceiveAll(buffer, bufLen, &dataLen); + + REQUIRE(NoteBinaryReceive_fake.call_count > 0); + THEN("The dataLen is set to zero") { + CHECK(dataLen == 0); + } + THEN("The error is returned") { + CHECK(!strcmp(err,errMsg)); + } + } + WHEN("No error is encountered") { + const char *err = NoteBinaryReceiveAll(buffer, bufLen, &dataLen); + + REQUIRE(NoteBinaryReceive_fake.call_count > 0); + THEN("The decoded length is returned") { + CHECK(dataLen == DECODED_LEN); + } + THEN("The return value is NULL") { + CHECK(err == NULL); + } + } + } +} + +} + +#endif // NOTE_C_TEST diff --git a/test/src/NoteBinaryReceiveRange_test.cpp b/test/src/NoteBinaryReceiveRange_test.cpp deleted file mode 100644 index 77d309be..00000000 --- a/test/src/NoteBinaryReceiveRange_test.cpp +++ /dev/null @@ -1,224 +0,0 @@ -/*! - * @file NoteBinaryReceiveRange_test.cpp - * - * Written by the Blues Inc. team. - * - * Copyright (c) 2023 Blues Inc. MIT License. Use of this source code is - * governed by licenses granted by the copyright holder including that found in - * the - * LICENSE - * file. - * - */ - -#ifdef NOTE_C_TEST - -#include -#include "fff.h" - -#include "n_lib.h" - -DEFINE_FFF_GLOBALS -FAKE_VALUE_FUNC(J *, NoteNewRequest, const char *) -FAKE_VALUE_FUNC(const char *, NoteBinaryDataEncodedLength, uint32_t *) -FAKE_VALUE_FUNC(J *, NoteRequestResponse, J *) -FAKE_VALUE_FUNC(const char *, NoteChunkedReceive, uint8_t *, uint32_t *, bool, - size_t, uint32_t *) -FAKE_VOID_FUNC(NoteLockNote) -FAKE_VOID_FUNC(NoteUnlockNote) - -// Most of these variables have to be global because they're accessed in -// lambda functions used as fakes for various note-c functions. They can't be -// captured by the lambdas because the lambdas need to be convertible to plain -// old function pointers in order to be used by the fff mocking/fake framework. -// If a lambda captures anything, it can't be converted in this way, and you get -// a compiler error. -uint8_t buf[32]; -uint32_t bufLen = sizeof(buf); -uint32_t decodedOffset = 0; -uint32_t decodedLen = 17; - -char rawMsg[] = "Hello Blues!"; -uint32_t rawMsgLen = strlen(rawMsg); - -namespace -{ - -SCENARIO("NoteBinaryReceiveRange") -{ - RESET_FAKE(NoteNewRequest); - RESET_FAKE(NoteBinaryDataEncodedLength); - RESET_FAKE(NoteRequestResponse); - RESET_FAKE(NoteChunkedReceive); - RESET_FAKE(NoteLockNote); - RESET_FAKE(NoteUnlockNote); - - NoteSetFnDefault(malloc, free, NULL, NULL); - - // These fakes are the default. Tests below may override them to exercise - // different scenarios. - NoteNewRequest_fake.custom_fake = [](const char *req) -> J* { - return JCreateObject(); - }; - NoteBinaryDataEncodedLength_fake.custom_fake = [](uint32_t *size) - -> const char * { - *size = bufLen; - - return NULL; - }; - NoteRequestResponse_fake.custom_fake = [](J *req) -> J * { - JDelete(req); - J *rsp = JCreateObject(); - char hash[NOTE_MD5_HASH_STRING_SIZE] = {0}; - NoteMD5HashString((unsigned char *)rawMsg, rawMsgLen, hash, - NOTE_MD5_HASH_STRING_SIZE); - JAddStringToObject(rsp, "status", hash); - - return rsp; - }; - - GIVEN("Bad parameters are supplied") { - WHEN("buffer is NULL") { - const char *err = NoteBinaryReceiveRange(NULL, bufLen, decodedOffset, decodedLen); - - THEN("An error is returned") { - CHECK(err != NULL); - } - } - WHEN("bufLen is too small") { - const char *err = NoteBinaryReceiveRange(buf, bufLen, decodedOffset, bufLen); - - THEN("An error is returned") { - CHECK(err != NULL); - } - } - WHEN("decodedLen is zero") { - const char *err = NoteBinaryReceiveRange(buf, bufLen, decodedOffset, 0); - - THEN("An error is returned") { - CHECK(err != NULL); - } - } - } - - GIVEN("Allocating the card.binary.get request fails") { - NoteNewRequest_fake.custom_fake = NULL; - NoteNewRequest_fake.return_val = NULL; - - WHEN("NoteBinaryReceiveRange is called") { - const char *err = NoteBinaryReceiveRange(buf, bufLen, decodedOffset, decodedLen); - - REQUIRE(NoteNewRequest_fake.call_count > 0); - THEN("An error is returned") { - CHECK(err != NULL); - } - } - } - - GIVEN("The response to the card.binary.get request has an error") { - NoteRequestResponse_fake.custom_fake = [](J *req) -> J * { - JDelete(req); - J *rsp = JCreateObject(); - JAddStringToObject(rsp, "err", "some error"); - - return rsp; - }; - - WHEN("NoteBinaryReceiveRange is called") { - const char *err = NoteBinaryReceiveRange(buf, bufLen, decodedOffset, decodedLen); - - REQUIRE(NoteRequestResponse_fake.call_count > 0); - THEN("An error is returned") { - CHECK(err != NULL); - } - } - } - - GIVEN("NoteChunkedReceive returns an error") { - NoteChunkedReceive_fake.return_val = "some error"; - - WHEN("NoteBinaryReceiveRange is called") { - const char *err = NoteBinaryReceiveRange(buf, bufLen, decodedOffset, decodedLen); - - REQUIRE(NoteChunkedReceive_fake.call_count > 0); - THEN("An error is returned") { - CHECK(err != NULL); - } - } - } - - GIVEN("NoteChunkedReceive indicates there's unexpectedly more data " - "available") { - NoteChunkedReceive_fake.custom_fake = [](uint8_t *, uint32_t *, bool, - size_t, uint32_t *available) -> const char* { - *available = 1; - - return NULL; - }; - - WHEN("NoteBinaryReceiveRange is called") { - const char *err = NoteBinaryReceiveRange(buf, bufLen, decodedOffset, decodedLen); - - REQUIRE(NoteChunkedReceive_fake.call_count > 0); - THEN("An error is returned") { - CHECK(err != NULL); - } - } - } - - GIVEN("The binary payload is received") { - NoteChunkedReceive_fake.custom_fake = [](uint8_t *buffer, uint32_t *size, - bool, size_t, uint32_t *available) -> const char* { - uint32_t outLen = 0; - NoteBinaryEncode((uint8_t *)rawMsg, rawMsgLen, buffer, *size, &outLen); - - buffer[outLen] = '\n'; - *size = outLen + 1; - *available = 0; - - return NULL; - }; - - AND_GIVEN("The computed MD5 hash doesn't match the status field") { - NoteRequestResponse_fake.custom_fake = [](J *req) -> J * { - JDelete(req); - J *rsp = JCreateObject(); - JAddStringToObject(rsp, "status", "garbage"); - - return rsp; - }; - - WHEN("NoteBinaryReceiveRange is called") { - const char *err = NoteBinaryReceiveRange(buf, bufLen, decodedOffset, decodedLen); - - REQUIRE(NoteChunkedReceive_fake.call_count > 0); - REQUIRE(NoteRequestResponse_fake.call_count > 0); - THEN("An error is returned") { - CHECK(err != NULL); - } - } - } - - AND_GIVEN("The computed MD5 matches the status field") { - WHEN("NoteBinaryReceiveRange is called") { - uint32_t decodedLen = rawMsgLen; - const char *err = NoteBinaryReceiveRange(buf, bufLen, decodedOffset, decodedLen); - - REQUIRE(NoteChunkedReceive_fake.call_count > 0); - THEN("No error is returned") { - CHECK(err == NULL); - } - - THEN("The decoded payload is as expected, with no trailing " - "newline") { - CHECK(memcmp(buf, rawMsg, decodedLen) == 0); - } - } - } - } - CHECK(NoteLockNote_fake.call_count == NoteUnlockNote_fake.call_count); -} - -} - -#endif // NOTE_C_TEST diff --git a/test/src/NoteBinaryReceive_test.cpp b/test/src/NoteBinaryReceive_test.cpp index 6714fd88..22d2e4db 100644 --- a/test/src/NoteBinaryReceive_test.cpp +++ b/test/src/NoteBinaryReceive_test.cpp @@ -19,32 +19,81 @@ #include "n_lib.h" DEFINE_FFF_GLOBALS -FAKE_VALUE_FUNC(const char *, NoteBinaryDataDecodedLength, uint32_t *) -FAKE_VALUE_FUNC(const char *, NoteBinaryReceiveRange, uint8_t *, uint32_t, uint32_t, uint32_t) - -uint8_t buffer[12]; -const uint32_t bufLen = sizeof(buffer); -uint32_t dataLen = 0; +FAKE_VALUE_FUNC(J *, NoteNewRequest, const char *) +FAKE_VALUE_FUNC(const char *, NoteBinaryDataEncodedLength, uint32_t *) +FAKE_VALUE_FUNC(J *, NoteRequestResponse, J *) +FAKE_VALUE_FUNC(const char *, NoteChunkedReceive, uint8_t *, uint32_t *, bool, + size_t, uint32_t *) +FAKE_VOID_FUNC(NoteLockNote) +FAKE_VOID_FUNC(NoteUnlockNote) + +// Most of these variables have to be global because they're accessed in +// lambda functions used as fakes for various note-c functions. They can't be +// captured by the lambdas because the lambdas need to be convertible to plain +// old function pointers in order to be used by the fff mocking/fake framework. +// If a lambda captures anything, it can't be converted in this way, and you get +// a compiler error. +uint8_t buf[32]; +uint32_t bufLen = sizeof(buf); +uint32_t decodedOffset = 0; +uint32_t decodedLen = 17; + +char rawMsg[] = "Hello Blues!"; +uint32_t rawMsgLen = strlen(rawMsg); namespace { SCENARIO("NoteBinaryReceive") { - RESET_FAKE(NoteBinaryDataDecodedLength); - RESET_FAKE(NoteBinaryReceiveRange); - dataLen = 17; + RESET_FAKE(NoteNewRequest); + RESET_FAKE(NoteBinaryDataEncodedLength); + RESET_FAKE(NoteRequestResponse); + RESET_FAKE(NoteChunkedReceive); + RESET_FAKE(NoteLockNote); + RESET_FAKE(NoteUnlockNote); + + NoteSetFnDefault(malloc, free, NULL, NULL); + + // These fakes are the default. Tests below may override them to exercise + // different scenarios. + NoteNewRequest_fake.custom_fake = [](const char *req) -> J* { + return JCreateObject(); + }; + NoteBinaryDataEncodedLength_fake.custom_fake = [](uint32_t *size) + -> const char * { + *size = bufLen; + + return NULL; + }; + NoteRequestResponse_fake.custom_fake = [](J *req) -> J * { + JDelete(req); + J *rsp = JCreateObject(); + char hash[NOTE_MD5_HASH_STRING_SIZE] = {0}; + NoteMD5HashString((unsigned char *)rawMsg, rawMsgLen, hash, + NOTE_MD5_HASH_STRING_SIZE); + JAddStringToObject(rsp, "status", hash); + + return rsp; + }; GIVEN("Bad parameters are supplied") { WHEN("buffer is NULL") { - const char *err = NoteBinaryReceive(NULL, bufLen, &dataLen); + const char *err = NoteBinaryReceive(NULL, bufLen, decodedOffset, decodedLen); + + THEN("An error is returned") { + CHECK(err != NULL); + } + } + WHEN("bufLen is too small") { + const char *err = NoteBinaryReceive(buf, bufLen, decodedOffset, bufLen); THEN("An error is returned") { CHECK(err != NULL); } } - WHEN("dataLen is NULL") { - const char *err = NoteBinaryReceive(buffer, bufLen, NULL); + WHEN("decodedLen is zero") { + const char *err = NoteBinaryReceive(buf, bufLen, decodedOffset, 0); THEN("An error is returned") { CHECK(err != NULL); @@ -52,71 +101,122 @@ SCENARIO("NoteBinaryReceive") } } - GIVEN("NoteBinaryDataDecodedLength() is invoked") { - WHEN("An error is encountered") { - const char *errMsg = "ERROR! Hacking too much time!"; - NoteBinaryDataDecodedLength_fake.return_val = errMsg; - const char *err = NoteBinaryReceive(buffer, bufLen, &dataLen); + GIVEN("Allocating the card.binary.get request fails") { + NoteNewRequest_fake.custom_fake = NULL; + NoteNewRequest_fake.return_val = NULL; - REQUIRE(NoteBinaryDataDecodedLength_fake.call_count > 0); - THEN("NoteBinaryReceiveRange() is not invoked") { - CHECK(NoteBinaryReceiveRange_fake.call_count == 0); - } - THEN("The dataLen is set to zero") { - CHECK(dataLen == 0); - } - THEN("The error is returned") { - CHECK(!strcmp(err,errMsg)); + WHEN("NoteBinaryReceive is called") { + const char *err = NoteBinaryReceive(buf, bufLen, decodedOffset, decodedLen); + + REQUIRE(NoteNewRequest_fake.call_count > 0); + THEN("An error is returned") { + CHECK(err != NULL); } } - WHEN("No error is encountered") { - const uint32_t DECODED_LEN = 79; - NoteBinaryDataDecodedLength_fake.custom_fake = [](uint32_t *len) -> const char * { - *len = DECODED_LEN; - return NULL; - }; - const char *err = NoteBinaryReceive(buffer, bufLen, &dataLen); + } + + GIVEN("The response to the card.binary.get request has an error") { + NoteRequestResponse_fake.custom_fake = [](J *req) -> J * { + JDelete(req); + J *rsp = JCreateObject(); + JAddStringToObject(rsp, "err", "some error"); + + return rsp; + }; + + WHEN("NoteBinaryReceive is called") { + const char *err = NoteBinaryReceive(buf, bufLen, decodedOffset, decodedLen); - REQUIRE(NoteBinaryDataDecodedLength_fake.call_count > 0); - THEN("NoteBinaryReceiveRange() is invoked") { - CHECK(NoteBinaryReceiveRange_fake.call_count > 0); + REQUIRE(NoteRequestResponse_fake.call_count > 0); + THEN("An error is returned") { + CHECK(err != NULL); } - THEN("The decoded length is passed to NoteBinaryReceiveRange()") { - CHECK(NoteBinaryReceiveRange_fake.arg3_history[0] == DECODED_LEN); + } + } + + GIVEN("NoteChunkedReceive returns an error") { + NoteChunkedReceive_fake.return_val = "some error"; + + WHEN("NoteBinaryReceive is called") { + const char *err = NoteBinaryReceive(buf, bufLen, decodedOffset, decodedLen); + + REQUIRE(NoteChunkedReceive_fake.call_count > 0); + THEN("An error is returned") { + CHECK(err != NULL); } } } - GIVEN("NoteBinaryReceiveRange() is invoked") { - const uint32_t DECODED_LEN = 79; - NoteBinaryDataDecodedLength_fake.custom_fake = [](uint32_t *len) -> const char * { - *len = DECODED_LEN; + + GIVEN("NoteChunkedReceive indicates there's unexpectedly more data " + "available") { + NoteChunkedReceive_fake.custom_fake = [](uint8_t *, uint32_t *, bool, + size_t, uint32_t *available) -> const char* { + *available = 1; + return NULL; }; - WHEN("An error is encountered") { - const char *errMsg = "ERROR! Hacking too much time!"; - NoteBinaryReceiveRange_fake.return_val = errMsg; - const char *err = NoteBinaryReceive(buffer, bufLen, &dataLen); - - REQUIRE(NoteBinaryReceiveRange_fake.call_count > 0); - THEN("The dataLen is set to zero") { - CHECK(dataLen == 0); - } - THEN("The error is returned") { - CHECK(!strcmp(err,errMsg)); + + WHEN("NoteBinaryReceive is called") { + const char *err = NoteBinaryReceive(buf, bufLen, decodedOffset, decodedLen); + + REQUIRE(NoteChunkedReceive_fake.call_count > 0); + THEN("An error is returned") { + CHECK(err != NULL); } } - WHEN("No error is encountered") { - const char *err = NoteBinaryReceive(buffer, bufLen, &dataLen); + } + + GIVEN("The binary payload is received") { + NoteChunkedReceive_fake.custom_fake = [](uint8_t *buffer, uint32_t *size, + bool, size_t, uint32_t *available) -> const char* { + uint32_t outLen = 0; + NoteBinaryEncode((uint8_t *)rawMsg, rawMsgLen, buffer, *size, &outLen); + + buffer[outLen] = '\n'; + *size = outLen + 1; + *available = 0; - REQUIRE(NoteBinaryReceiveRange_fake.call_count > 0); - THEN("The decoded length is returned") { - CHECK(dataLen == DECODED_LEN); + return NULL; + }; + + AND_GIVEN("The computed MD5 hash doesn't match the status field") { + NoteRequestResponse_fake.custom_fake = [](J *req) -> J * { + JDelete(req); + J *rsp = JCreateObject(); + JAddStringToObject(rsp, "status", "garbage"); + + return rsp; + }; + + WHEN("NoteBinaryReceive is called") { + const char *err = NoteBinaryReceive(buf, bufLen, decodedOffset, decodedLen); + + REQUIRE(NoteChunkedReceive_fake.call_count > 0); + REQUIRE(NoteRequestResponse_fake.call_count > 0); + THEN("An error is returned") { + CHECK(err != NULL); + } } - THEN("The return value is NULL") { - CHECK(err == NULL); + } + + AND_GIVEN("The computed MD5 matches the status field") { + WHEN("NoteBinaryReceive is called") { + uint32_t decodedLen = rawMsgLen; + const char *err = NoteBinaryReceive(buf, bufLen, decodedOffset, decodedLen); + + REQUIRE(NoteChunkedReceive_fake.call_count > 0); + THEN("No error is returned") { + CHECK(err == NULL); + } + + THEN("The decoded payload is as expected, with no trailing " + "newline") { + CHECK(memcmp(buf, rawMsg, decodedLen) == 0); + } } } } + CHECK(NoteLockNote_fake.call_count == NoteUnlockNote_fake.call_count); } }