class TestResultData(unittest.TestCase): def setUp(self): self.resultData = ResultData() def testInit(self): self.assertEqual(self.resultData.getValue(self.resultData.RESULT_KEY_CRYPTO), None) self.assertEqual(self.resultData.getValue(self.resultData.RESULT_KEY_FIAT), None) self.assertEqual(self.resultData.getValue(self.resultData.RESULT_KEY_EXCHANGE), None) self.assertEqual(self.resultData.getValue(self.resultData.RESULT_KEY_PRICE_TIME_STAMP), None) self.assertEqual(self.resultData.getValue(self.resultData.RESULT_KEY_PRICE_DATE_TIME_STRING), None) self.assertEqual(self.resultData.getValue(self.resultData.RESULT_KEY_PRICE), None) self.assertEqual(self.resultData.getValue(self.resultData.RESULT_KEY_PRICE_TYPE), None) self.assertEqual(self.resultData.getValue(self.resultData.RESULT_KEY_ERROR_MSG), None) self.assertEqual(self.resultData.getValue(self.resultData.RESULT_KEY_PRICE_VALUE_FIAT), None) self.assertEqual(self.resultData.getValue(self.resultData.RESULT_KEY_PRICE_VALUE_CRYPTO), None) self.assertEqual(self.resultData.getValue(self.resultData.RESULT_KEY_PRICE_VALUE_SAVE), None) def testIsEmpty(self): self.assertTrue(self.resultData.isEmpty(self.resultData.RESULT_KEY_CRYPTO)) def testSetValue(self): self.resultData.setValue(self.resultData.RESULT_KEY_CRYPTO, 'USD') self.assertEqual(self.resultData.getValue(self.resultData.RESULT_KEY_CRYPTO), 'USD') def testSetGetWarning(self): commValWarningMsg = "test warning command value" futureDateWarningMsg = "test warning future date" self.resultData.setWarning(ResultData.WARNING_TYPE_COMMAND_VALUE, commValWarningMsg) self.resultData.setWarning(ResultData.WARNING_TYPE_FUTURE_DATE, futureDateWarningMsg) self.assertEqual(commValWarningMsg, self.resultData.getWarningMessage(ResultData.WARNING_TYPE_COMMAND_VALUE)) self.assertEqual(futureDateWarningMsg, self.resultData.getWarningMessage(ResultData.WARNING_TYPE_FUTURE_DATE)) def testGetAllWarningMessages(self): commValWarningMsg = "test warning command value" futureDateWarningMsg = "test warning future date" self.resultData.setWarning(ResultData.WARNING_TYPE_COMMAND_VALUE, commValWarningMsg) self.resultData.setWarning(ResultData.WARNING_TYPE_FUTURE_DATE, futureDateWarningMsg) self.assertEqual([commValWarningMsg, futureDateWarningMsg], self.resultData.getAllWarningMessages()) def testContainsWarning(self): commValWarningMsg = "test warning command value" futureDateWarningMsg = "test warning future date" self.assertFalse(self.resultData.containsWarnings()) self.resultData.setWarning(ResultData.WARNING_TYPE_COMMAND_VALUE, commValWarningMsg) self.assertTrue(self.resultData.containsWarning(ResultData.WARNING_TYPE_COMMAND_VALUE)) self.assertFalse(self.resultData.containsWarning(ResultData.WARNING_TYPE_FUTURE_DATE)) self.resultData.setWarning(ResultData.WARNING_TYPE_FUTURE_DATE, futureDateWarningMsg) self.assertTrue(self.resultData.containsWarning(ResultData.WARNING_TYPE_FUTURE_DATE)) def testOverwriteWarning(self): commValWarningMsgOne = "test warning command value one" futureDateWarningMsgOne = "test warning future date one" self.resultData.setWarning(ResultData.WARNING_TYPE_COMMAND_VALUE, commValWarningMsgOne) self.resultData.setWarning(ResultData.WARNING_TYPE_FUTURE_DATE, futureDateWarningMsgOne) commValWarningMsgTwo = "test warning command value two" futureDateWarningMsgTwo = "test warning future date two" self.resultData.setWarning(ResultData.WARNING_TYPE_COMMAND_VALUE, commValWarningMsgTwo) self.resultData.setWarning(ResultData.WARNING_TYPE_FUTURE_DATE, futureDateWarningMsgTwo) self.assertEqual(commValWarningMsgTwo, self.resultData.getWarningMessage(ResultData.WARNING_TYPE_COMMAND_VALUE)) self.assertEqual(futureDateWarningMsgTwo, self.resultData.getWarningMessage(ResultData.WARNING_TYPE_FUTURE_DATE))
def getCryptoPrice(self, crypto, fiat, exchange, day, month, year, hour, minute, priceValueSymbol = None, priceValueAmount = None, priceValueSaveFlag = None, requestInputString = ''): ''' Ask the PriceRequester either a RT price or a historical price. Then, in case a price value parm (-v) was specified, does the conversion and add its result to the returned ResultData :param crypto: upper case crypto symbol :param fiat: upper case fiat symbol :param exchange: exchange name :param day: int day number :param month: int month number :param year: int year number :param hour: int hour number :param minute: int minute number :param priceValueSymbol: upper case price value symbol. If == crypto, this means that priceValueAmount provided is in crypto and must be converted into fiat at the rate returned by the PriceRequester. If the price value symbol == fiat, this means that priceValueAmount provided is in fiat and must be converted into crypto at the rate returned by the PriceRequester. Ex 1: -v0.001btc crypto == BTC fiat == USD priceValueSymbol == BTC priceValueAmount == 0.001 if returned rate (stored in ResultData.RESULT_KEY_PRICE entry) is 20000, converted value will be 20000 USD * 0.001 BTC => 200 USD Ex 2: -v500usd crypto == BTC fiat == USD priceValueSymbol == USD priceValueAmount == 500 if returned rate (stored in ResultData.RESULT_KEY_PRICE entry) is 20000, converted value will be 1 / 20000 USD * 500 USD => 0.025 BTC :param priceValueAmount: float price value amount :param priceValueSaveFlag: used to refine warning if value command not applicable :param requestInputString): used for better error msg ! :seqdiag_return ResultData :return: a ResultData filled with result values ''' if exchange == None: resultData = ResultData() resultData.setValue(ResultData.RESULT_KEY_ERROR_MSG, "ERROR - exchange could not be parsed due to an error in your request ({})".format(requestInputString)) return resultData else: #this responsability is specific to the PriceRequester and should be moved to it ! try: validExchangeSymbol = self.crypCompExchanges.getExchange(exchange) except(KeyError): resultData = ResultData() resultData.setValue(ResultData.RESULT_KEY_ERROR_MSG, "ERROR - {} market does not exist for this coin pair ({}-{})".format(exchange, crypto, fiat)) return resultData localTz = self.configManager.localTimeZone dateTimeFormat = self.configManager.dateTimeFormat if (day + month + year) == 0: # when the user specifies 0 for either the date, # this means current price is asked and date components # are set to zero ! resultData = self.priceRequester.getCurrentPrice(crypto, fiat, validExchangeSymbol) if resultData.isEmpty(ResultData.RESULT_KEY_ERROR_MSG): #adding date time info if no error returned timeStamp = resultData.getValue(ResultData.RESULT_KEY_PRICE_TIME_STAMP) requestedPriceArrowLocalDateTime = DateTimeUtil.timeStampToArrowLocalDate(timeStamp, localTz) requestedDateTimeStr = requestedPriceArrowLocalDateTime.format(dateTimeFormat) resultData.setValue(ResultData.RESULT_KEY_PRICE_DATE_TIME_STRING, requestedDateTimeStr) else: #getting historical price, either histo day or histo minute timeStampLocal = DateTimeUtil.dateTimeComponentsToTimeStamp(day, month, year, hour, minute, 0, localTz) timeStampUtcNoHHMM = DateTimeUtil.dateTimeComponentsToTimeStamp(day, month, year, 0, 0, 0, 'UTC') resultData = self.priceRequester.getHistoricalPriceAtUTCTimeStamp(crypto, fiat, timeStampLocal, timeStampUtcNoHHMM, validExchangeSymbol) if resultData.isEmpty(ResultData.RESULT_KEY_ERROR_MSG): #adding date time info if no error returned if resultData.getValue(ResultData.RESULT_KEY_PRICE_TYPE) == ResultData.PRICE_TYPE_HISTO_DAY: #histoday price returned requestedPriceArrowUtcDateTime = DateTimeUtil.timeStampToArrowLocalDate(timeStampUtcNoHHMM, 'UTC') requestedDateTimeStr = requestedPriceArrowUtcDateTime.format(self.configManager.dateTimeFormat) else: requestedPriceArrowLocalDateTime = DateTimeUtil.timeStampToArrowLocalDate(timeStampLocal, localTz) requestedDateTimeStr = requestedPriceArrowLocalDateTime.format(dateTimeFormat) resultData.setValue(ResultData.RESULT_KEY_PRICE_DATE_TIME_STRING, requestedDateTimeStr) if priceValueSymbol != None and not resultData.isError(): resultData = self._computePriceValue(resultData, crypto, fiat, priceValueSymbol, priceValueAmount, priceValueSaveFlag) return resultData