Beispiel #1
0
    def run_test(self):
        alice = self.nodes[1]
        bob = self.nodes[2]
        charlie = self.nodes[3]

        # generate some coins and send them to bob
        time.sleep(4)
        api_url = bob["gateway_url"] + "wallet/address/" + self.cointype
        r = requests.get(api_url)
        if r.status_code == 200:
            resp = json.loads(r.text)
            address = resp["address"]
        elif r.status_code == 404:
            raise TestFailure(
                "EthPurchaseModeratedOfflineTest - FAIL: Address endpoint not found"
            )
        else:
            raise TestFailure(
                "EthPurchaseModeratedOfflineTest - FAIL: Unknown response")
        time.sleep(20)

        # create a profile for charlie
        pro = {"name": "Charlie"}
        api_url = charlie["gateway_url"] + "ob/profile"
        r = requests.post(api_url, data=json.dumps(pro, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "EthPurchaseModeratedOfflineTest - FAIL: Profile post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "EthPurchaseModeratedOfflineTest - FAIL: Profile POST failed. Reason: %s",
                resp["reason"])
        time.sleep(4)

        # make charlie a moderator
        with open('testdata/v5/moderation.json') as listing_file:
            moderation_json = json.load(listing_file,
                                        object_pairs_hook=OrderedDict)
        api_url = charlie["gateway_url"] + "ob/moderator"
        r = requests.put(api_url, data=json.dumps(moderation_json, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "EthPurchaseModeratedOfflineTest - FAIL: Moderator post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "EthPurchaseModeratedOfflineTest - FAIL: Moderator POST failed. Reason: %s",
                resp["reason"])
        moderatorId = charlie["peerId"]
        time.sleep(4)

        # post profile for alice
        with open('testdata/v5/profile.json') as profile_file:
            profile_json = json.load(profile_file,
                                     object_pairs_hook=OrderedDict)
        api_url = alice["gateway_url"] + "ob/profile"
        requests.post(api_url, data=json.dumps(profile_json, indent=4))

        # post listing to alice
        with open('testdata/v5/eth_listing.json') as listing_file:
            listing_json = json.load(listing_file,
                                     object_pairs_hook=OrderedDict)
        listing_json["item"]["priceCurrency"]["code"] = "T" + self.cointype
        listing_json["metadata"]["acceptedCurrencies"] = ["T" + self.cointype]

        api_url = alice["gateway_url"] + "ob/listing"
        listing_json["moderators"] = [moderatorId]
        r = requests.post(api_url, data=json.dumps(listing_json, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "EthPurchaseModeratedOfflineTest - FAIL: Listing post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "EthPurchaseModeratedOfflineTest - FAIL: Listing POST failed. Reason: %s",
                resp["reason"])
        time.sleep(4)

        # get listing hash
        api_url = alice["gateway_url"] + "ob/listings/" + alice["peerId"]
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "EthPurchaseModeratedOfflineTest - FAIL: Couldn't get listing index"
            )
        resp = json.loads(r.text)
        listingId = resp[0]["hash"]

        # bob fetch listing to cache
        api_url = bob["gateway_url"] + "ipfs/" + listingId
        requests.get(api_url)

        # shutdown alice
        api_url = alice["gateway_url"] + "ob/shutdown"
        requests.post(api_url, data="")
        time.sleep(10)

        # bob send order
        with open('testdata/v5/order_direct.json') as order_file:
            order_json = json.load(order_file, object_pairs_hook=OrderedDict)
        order_json["items"][0]["listingHash"] = listingId
        order_json["moderator"] = moderatorId
        order_json["paymentCoin"] = "T" + self.cointype
        api_url = bob["gateway_url"] + "ob/purchase"
        r = requests.post(api_url, data=json.dumps(order_json, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "EthPurchaseModeratedOfflineTest - FAIL: Purchase post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "EthPurchaseModeratedOfflineTest - FAIL: Purchase POST failed. Reason: %s",
                resp["reason"])
        resp = json.loads(r.text)
        orderId = resp["orderId"]
        payment_address = resp["paymentAddress"]
        payment_amount = resp["amount"]
        if resp["vendorOnline"] == True:
            raise TestFailure(
                "EthPurchaseModeratedOfflineTest - FAIL: Purchase returned vendor is online"
            )

        # check the purchase saved correctly
        api_url = bob["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "EthPurchaseModeratedOfflineTest - FAIL: Couldn't load order from Bob"
            )
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_PAYMENT":
            raise TestFailure(
                "EthPurchaseModeratedOfflineTest - FAIL: Bob purchase saved in incorrect state"
            )
        if resp["funded"] == True:
            raise TestFailure(
                "EthPurchaseModeratedOfflineTest - FAIL: Bob incorrectly saved as funded"
            )

        # fund order
        spend = {
            "currencyCode": "T" + self.cointype,
            "address": payment_address,
            "amount": payment_amount["amount"],
            "feeLevel": "NORMAL",
            "requireAssociateOrder": True,
            "orderID": orderId
        }
        api_url = bob["gateway_url"] + "ob/orderspend"
        r = requests.post(api_url, data=json.dumps(spend, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "EthPurchaseModeratedOfflineTest - FAIL: Spend post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "EthPurchaseModeratedOfflineTest - FAIL: Purchase POST failed. Reason: %s",
                resp["reason"])
        time.sleep(20)

        # check bob detected payment
        api_url = bob["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "EthPurchaseModeratedOfflineTest - FAIL: Couldn't load order from Bob"
            )
        resp = json.loads(r.text)
        if len(resp["paymentAddressTransactions"]) <= 0:
            raise TestFailure(
                "EthPurchaseModeratedOfflineTest - FAIL: Bob failed to detect his payment"
            )
        if resp["funded"] == False:
            raise TestFailure(
                "EthPurchaseModeratedOfflineTest - FAIL: Bob incorrectly saved as unfunded"
            )
        if resp["state"] != "PENDING":
            raise TestFailure(
                "EthPurchaseModeratedOfflineTest - FAIL: Bob purchase saved in incorrect state"
            )

        # startup alice again
        self.start_node(1, alice)
        time.sleep(80)

        # check alice detected order and payment
        api_url = alice["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "EthPurchaseModeratedOfflineTest - FAIL: Couldn't load order from Alice %s",
                r.status_code)
        resp = json.loads(r.text)
        if resp["state"] != "PENDING":
            raise TestFailure(
                "EthPurchaseModeratedOfflineTest - FAIL: Alice failed to detect initial payment"
            )
        if resp["funded"] == False:
            raise TestFailure(
                "EthPurchaseModeratedOfflineTest - FAIL: Alice incorrectly saved as unfunded"
            )

        # check alice balance is zero
        api_url = alice["gateway_url"] + "wallet/balance/T" + self.cointype
        r = requests.get(api_url)
        if r.status_code == 200:
            resp = json.loads(r.text)
            confirmed = int(resp["confirmed"])
            unconfirmed = int(resp["unconfirmed"])
            ##if confirmed + unconfirmed > 0:
            ##    raise TestFailure("EthPurchaseModeratedOfflineTest - FAIL: Alice should have zero balance at this point")
        else:
            raise TestFailure(
                "EthPurchaseModeratedOfflineTest - FAIL: Failed to query Alice's balance"
            )
        time.sleep(1)

        # alice confirm offline order
        api_url = alice["gateway_url"] + "ob/orderconfirmation"
        oc = {"orderId": orderId, "reject": False}
        r = requests.post(api_url, data=json.dumps(oc, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "EthPurchaseModeratedOfflineTest - FAIL: Order confirmation post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "EthPurchaseModeratedOfflineTest - FAIL: Purchase POST failed. Reason: %s",
                resp["reason"])
        time.sleep(10)

        # check bob detected order confirmation
        api_url = bob["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "PurchaseDirectOnlineTest - FAIL: Couldn't load order from Bob"
            )
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_FULFILLMENT":
            raise TestFailure(
                "PurchaseDirectOnlineTest - FAIL: Bob failed to set state correctly"
            )
        if resp["funded"] == False:
            raise TestFailure(
                "PurchaseDirectOnlineTest - FAIL: Bob incorrectly saved as unfunded"
            )

        # check alice set state correctly
        api_url = alice["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "PurchaseDirectOnlineTest - FAIL: Couldn't load order from Alice"
            )
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_FULFILLMENT":
            raise TestFailure(
                "PurchaseDirectOnlineTest - FAIL: Alice failed to detect payment"
            )
        if resp["funded"] == False:
            raise TestFailure(
                "PurchaseDirectOnlineTest - FAIL: Alice incorrectly saved as unfunded"
            )

        print("EthPurchaseModeratedOfflineTest - PASS")
    def run_test(self):
        alice = self.nodes[1]
        bob = self.nodes[2]
        charlie = self.nodes[3]

        # generate some coins and send them to bob
        time.sleep(4)
        api_url = bob["gateway_url"] + "wallet/address/" + self.cointype
        r = requests.get(api_url)
        if r.status_code == 200:
            resp = json.loads(r.text)
            address = resp["address"]
        elif r.status_code == 404:
            raise TestFailure(
                "EthPurchaseModeratedOnlineTest - FAIL: Address endpoint not found"
            )
        else:
            raise TestFailure(
                "EthPurchaseModeratedOnlineTest - FAIL: Unknown response")
        time.sleep(20)

        # create a profile for charlie
        pro = {"name": "Charlie"}
        api_url = charlie["gateway_url"] + "ob/profile"
        r = requests.post(api_url, data=json.dumps(pro, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "EthPurchaseModeratedOnlineTest - FAIL: Profile post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "EthPurchaseModeratedOnlineTest - FAIL: Profile POST failed. Reason: %s",
                resp["reason"])
        time.sleep(4)

        # make charlie a moderator
        with open('testdata/v5/moderation.json') as listing_file:
            moderation_json = json.load(listing_file,
                                        object_pairs_hook=OrderedDict)
        api_url = charlie["gateway_url"] + "ob/moderator"
        r = requests.put(api_url, data=json.dumps(moderation_json, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "EthPurchaseModeratedOnlineTest - FAIL: Moderator post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "EthPurchaseModeratedOnlineTest - FAIL: Moderator POST failed. Reason: %s",
                resp["reason"])
        moderatorId = charlie["peerId"]
        time.sleep(4)

        # post profile for alice
        with open('testdata/v5/profile.json') as profile_file:
            profile_json = json.load(profile_file,
                                     object_pairs_hook=OrderedDict)
        api_url = alice["gateway_url"] + "ob/profile"
        requests.post(api_url, data=json.dumps(profile_json, indent=4))

        # post listing to alice
        with open('testdata/v5/eth_listing.json') as listing_file:
            listing_json = json.load(listing_file,
                                     object_pairs_hook=OrderedDict)
        listing_json["item"]["priceCurrency"]["code"] = "T" + self.cointype
        listing_json["metadata"]["acceptedCurrencies"] = ["T" + self.cointype]

        listing_json["moderators"] = [moderatorId]
        api_url = alice["gateway_url"] + "ob/listing"
        r = requests.post(api_url, data=json.dumps(listing_json, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "EthPurchaseModeratedOnlineTest - FAIL: Listing post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "EthPurchaseModeratedOnlineTest - FAIL: Listing POST failed. Reason: %s",
                resp["reason"])
        time.sleep(4)

        # get listing hash
        api_url = alice["gateway_url"] + "ob/listings/" + alice["peerId"]
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "EthPurchaseModeratedOnlineTest - FAIL: Couldn't get listing index"
            )
        resp = json.loads(r.text)
        listingId = resp[0]["hash"]

        # bob send order
        with open('testdata/v5/order_direct.json') as order_file:
            order_json = json.load(order_file, object_pairs_hook=OrderedDict)
        order_json["items"][0]["listingHash"] = listingId
        order_json["moderator"] = moderatorId
        order_json["paymentCoin"] = "T" + self.cointype
        api_url = bob["gateway_url"] + "ob/purchase"
        r = requests.post(api_url, data=json.dumps(order_json, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "EthPurchaseModeratedOnlineTest - FAIL: Purchase post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            self.print_logs(alice, "ob.log")
            raise TestFailure(
                "EthPurchaseModeratedOnlineTest - FAIL: Purchase POST failed. Reason: %s",
                resp["reason"])
        resp = json.loads(r.text)
        orderId = resp["orderId"]
        payment_address = resp["paymentAddress"]
        payment_amount = resp["amount"]

        # check the purchase saved correctly
        api_url = bob["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "EthPurchaseModeratedOnlineTest - FAIL: Couldn't load order from Bob"
            )
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_PAYMENT":
            raise TestFailure(
                "EthPurchaseModeratedOnlineTest - FAIL: Bob purchase saved in incorrect state"
            )
        if resp["funded"] == True:
            raise TestFailure(
                "EthPurchaseModeratedOnlineTest - FAIL: Bob incorrectly saved as funded"
            )

        # check the sale saved correctly
        api_url = alice["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "EthPurchaseModeratedOnlineTest - FAIL: Couldn't load order from Alice"
            )
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_PAYMENT":
            raise TestFailure(
                "EthPurchaseModeratedOnlineTest - FAIL: Alice purchase saved in incorrect state"
            )
        if resp["funded"] == True:
            raise TestFailure(
                "EthPurchaseModeratedOnlineTest - FAIL: Alice incorrectly saved as funded"
            )

        # fund order
        spend = {
            "currencyCode": "T" + self.cointype,
            "address": payment_address,
            "amount": payment_amount["amount"],
            "feeLevel": "NORMAL",
            "requireAssociateOrder": True,
            "orderID": orderId
        }
        api_url = bob["gateway_url"] + "ob/orderspend"
        r = requests.post(api_url, data=json.dumps(spend, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "EthPurchaseModeratedOnlineTest - FAIL: Spend post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "EthPurchaseModeratedOnlineTest - FAIL: Spend POST failed. Reason: %s",
                resp["reason"])
        time.sleep(60)

        # check bob detected payment
        api_url = bob["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "EthPurchaseModeratedOnlineTest - FAIL: Couldn't load order from Bob"
            )
        resp = json.loads(r.text)
        print("lets see bob's resp : ")
        print(resp)
        if resp["state"] != "AWAITING_FULFILLMENT":
            raise TestFailure(
                "EthPurchaseModeratedOnlineTest - FAIL: Bob failed to detect his payment"
            )
        if resp["funded"] == False:
            raise TestFailure(
                "EthPurchaseModeratedOnlineTest - FAIL: Bob incorrectly saved as unfunded"
            )

        # check alice detected payment
        api_url = alice["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "EthPurchaseModeratedOnlineTest - FAIL: Couldn't load order from Alice"
            )
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_FULFILLMENT":
            raise TestFailure(
                "EthPurchaseModeratedOnlineTest - FAIL: Alice failed to detect payment"
            )
        if resp["funded"] == False:
            raise TestFailure(
                "EthPurchaseModeratedOnlineTest - FAIL: Alice incorrectly saved as unfunded"
            )

        print("EthPurchaseModeratedOnlineTest - PASS")
Beispiel #3
0
    def run_test(self):
        vendor = self.nodes[0]
        buyer = self.nodes[1]

        # generate some coins and send them to buyer
        time.sleep(4)
        api_url = buyer["gateway_url"] + "wallet/address"
        r = requests.get(api_url)
        if r.status_code == 200:
            resp = json.loads(r.text)
            address = resp["address"]
        elif r.status_code == 404:
            raise TestFailure(
                "MarketPriceModifierTest - FAIL: Address endpoint not found")
        else:
            raise TestFailure(
                "MarketPriceModifierTest - FAIL: Unknown response")
        self.send_bitcoin_cmd("sendtoaddress", address, 10)
        time.sleep(20)

        # post profile for vendor
        with open('testdata/profile.json') as profile_file:
            profile_json = json.load(profile_file,
                                     object_pairs_hook=OrderedDict)
        api_url = vendor["gateway_url"] + "ob/profile"
        requests.post(api_url, data=json.dumps(profile_json, indent=4))

        # post listings to vendor
        with open('testdata/listing_crypto.json') as listing_file:
            listing_json = json.load(listing_file,
                                     object_pairs_hook=OrderedDict)
            listing_json_with_modifier = deepcopy(listing_json)
            listing_json_with_modifier["metadata"][
                "priceModifier"] = self.price_modifier

        api_url = vendor["gateway_url"] + "ob/listing"
        r = requests.post(api_url, data=json.dumps(listing_json, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "MarketPriceModifierTest - FAIL: Listing post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "MarketPriceModifierTest - FAIL: Listing POST failed. Reason: %s",
                resp["reason"])
        slug = json.loads(r.text)["slug"]

        api_url = vendor["gateway_url"] + "ob/listing"
        r = requests.post(api_url,
                          data=json.dumps(listing_json_with_modifier,
                                          indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "MarketPriceModifierTest - FAIL: Listing post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "MarketPriceModifierTest - FAIL: Listing POST failed. Reason: %s",
                resp["reason"])
        slug_with_modifier = json.loads(r.text)["slug"]

        # check vendor's local listings and check for modifier
        api_url = vendor["gateway_url"] + "ob/listings"
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "MarketPriceModifierTest - FAIL: Couldn't get vendor local listings"
            )
        resp = json.loads(r.text)
        for listing in resp:
            if "modifier" not in listing["price"]:
                raise TestFailure(
                    "MarketPriceModifierTest - FAIL: Vendor's local listings index doesn't include price modifier"
                )

        # check vendor's listings from buyer and check for modifier
        api_url = buyer["gateway_url"] + "ob/listings/" + vendor["peerId"]
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "MarketPriceModifierTest - FAIL: Couldn't get vendor listings from buyer"
            )
        resp = json.loads(r.text)
        for listing in resp:
            if "modifier" not in listing["price"]:
                raise TestFailure(
                    "MarketPriceModifierTest - FAIL: Vendor's listings don't include price modifier from buyer"
                )

        # get listing hashes
        api_url = vendor["gateway_url"] + "ipns/" + vendor[
            "peerId"] + "/listings.json"
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "MarketPriceModifierTest - FAIL: Couldn't get listing index")
        resp = json.loads(r.text)
        listing_id = resp[0]["hash"]
        listing_id_with_modifier = resp[1]["hash"]

        # get second listing and check for modifier
        slug = resp[1]["slug"]
        api_url = buyer["gateway_url"] + "ob/listing/" + vendor[
            "peerId"] + "/" + slug
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "MarketPriceModifierTest - FAIL: Couldn't get vendor listings")
        resp = json.loads(r.text)
        if "priceModifier" not in resp["listing"]["metadata"]:
            raise TestFailure(
                "MarketPriceModifierTest - FAIL: Listing doesn't include priceModifier"
            )

        # buyer send orders
        with open('testdata/order_crypto.json') as order_file:
            order_json = json.load(order_file, object_pairs_hook=OrderedDict)
        order_json["items"][0]["listingHash"] = listing_id
        api_url = buyer["gateway_url"] + "ob/purchase"
        r = requests.post(api_url, data=json.dumps(order_json, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "MarketPriceModifierTest - FAIL: Purchase post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "MarketPriceModifierTest - FAIL: Purchase POST failed. Reason: %s",
                resp["reason"])
        resp = json.loads(r.text)
        payment_address = resp["paymentAddress"]
        payment_amount = resp["amount"]

        with open('testdata/order_crypto.json') as order_file:
            order_json = json.load(order_file, object_pairs_hook=OrderedDict)
        order_json["items"][0]["listingHash"] = listing_id_with_modifier
        api_url = buyer["gateway_url"] + "ob/purchase"
        r = requests.post(api_url, data=json.dumps(order_json, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "MarketPriceModifierTest - FAIL: Purchase post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "MarketPriceModifierTest - FAIL: Purchase POST failed. Reason: %s",
                resp["reason"])
        resp = json.loads(r.text)
        payment_address_with_modifier = resp["paymentAddress"]
        payment_amount_with_modifier = resp["amount"]

        # Check that modified price is different than regular price
        pct_change = round((payment_amount - payment_amount_with_modifier) /
                           payment_amount * -100, 2)
        if pct_change != self.price_modifier:
            raise TestFailure(
                "MarketPriceModifierTest - FAIL: Incorrect price modification: wanted %f but got %f",
                self.price_modifier, pct_change)

        print("MarketPriceModifierTest - PASS")
Beispiel #4
0
    def run_test(self):
        alice = self.nodes[1]
        bob = self.nodes[2]

        # generate some coins and send them to bob
        time.sleep(4)
        api_url = bob["gateway_url"] + "wallet/address/" + self.cointype
        r = requests.get(api_url)
        if r.status_code == 200:
            resp = json.loads(r.text)
            address = resp["address"]
        elif r.status_code == 404:
            raise TestFailure(
                "PurchaseDigital - FAIL: Address endpoint not found")
        else:
            raise TestFailure("PurchaseDigital - FAIL: Unknown response")
        self.send_bitcoin_cmd("sendtoaddress", address, 10)
        time.sleep(20)

        # post profile for alice
        with open('testdata/profile.json') as profile_file:
            profile_json = json.load(profile_file,
                                     object_pairs_hook=OrderedDict)
        api_url = alice["gateway_url"] + "ob/profile"
        requests.post(api_url, data=json.dumps(profile_json, indent=4))

        # post listing to alice
        with open('testdata/digital.json') as listing_file:
            listing_json = json.load(listing_file,
                                     object_pairs_hook=OrderedDict)
        listing_json["item"]["priceCurrency"]["code"] = "t" + self.cointype
        listing_json["metadata"]["acceptedCurrencies"] = ["t" + self.cointype]

        api_url = alice["gateway_url"] + "ob/listing"
        r = requests.post(api_url, data=json.dumps(listing_json, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "PurchaseDigital - FAIL: Listing post endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "PurchaseDigital - FAIL: Listing POST failed. Reason: %s",
                resp["reason"])
        time.sleep(4)

        # get listing hash
        api_url = alice["gateway_url"] + "ob/listings/" + alice["peerId"]
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "PurchaseDigital - FAIL: Couldn't get listing index")
        resp = json.loads(r.text)
        listingId = resp[0]["hash"]

        # bob send order
        with open('testdata/order_digital.json') as order_file:
            order_json = json.load(order_file, object_pairs_hook=OrderedDict)
        order_json["items"][0]["listingHash"] = listingId
        order_json["paymentCoin"] = "t" + self.cointype
        api_url = bob["gateway_url"] + "ob/purchase"
        r = requests.post(api_url, data=json.dumps(order_json, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "PurchaseDigital - FAIL: Purchase post endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "PurchaseDigital - FAIL: Purchase POST failed. Reason: %s",
                resp["reason"])
        resp = json.loads(r.text)
        orderId = resp["orderId"]
        payment_address = resp["paymentAddress"]
        payment_amount = resp["amount"]

        # check the purchase saved correctly
        api_url = bob["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "PurchaseDigital - FAIL: Couldn't load order from Bob")
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_PAYMENT":
            raise TestFailure(
                "PurchaseDigital - FAIL: Bob purchase saved in incorrect state"
            )
        if resp["funded"] == True:
            raise TestFailure(
                "PurchaseDigital - FAIL: Bob incorrectly saved as funded")

        # check the sale saved correctly
        api_url = alice["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "PurchaseDigital - FAIL: Couldn't load order from Alice")
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_PAYMENT":
            raise TestFailure(
                "PurchaseDigital - FAIL: Alice purchase saved in incorrect state"
            )
        if resp["funded"] == True:
            raise TestFailure(
                "PurchaseDigital - FAIL: Alice incorrectly saved as funded")

        # fund order
        spend = {
            "currencyCode": "T" + self.cointype,
            "address": payment_address,
            "amount": payment_amount["amount"],
            "feeLevel": "NORMAL",
            "requireAssociateOrder": False
        }
        api_url = bob["gateway_url"] + "wallet/spend"
        r = requests.post(api_url, data=json.dumps(spend, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "PurchaseDigital - FAIL: Spend post endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "PurchaseDigital - FAIL: Spend POST failed. Reason: %s",
                resp["reason"])
        time.sleep(20)

        # check bob detected payment
        api_url = bob["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "PurchaseDigital - FAIL: Couldn't load order from Bob")
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_FULFILLMENT":
            raise TestFailure(
                "PurchaseDigital - FAIL: Bob failed to detect his payment")
        if resp["funded"] == False:
            raise TestFailure(
                "PurchaseDigital - FAIL: Bob incorrectly saved as unfunded")

        # check alice detected payment
        api_url = alice["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "PurchaseDigital - FAIL: Couldn't load order from Alice")
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_FULFILLMENT":
            raise TestFailure(
                "PurchaseDigital - FAIL: Alice failed to detect payment")
        if resp["funded"] == False:
            raise TestFailure(
                "PurchaseDigital - FAIL: Alice incorrectly saved as unfunded")

        print("PurchaseDigital - PASS")
    def run_test(self):
        alice = self.nodes[0]
        bob = self.nodes[1]
        charlie = self.nodes[2]

        # generate some coins and send them to bob
        time.sleep(4)
        generated_coins = 10
        api_url = bob["gateway_url"] + "wallet/address/" + self.cointype
        r = requests.get(api_url)
        if r.status_code == 200:
            resp = json.loads(r.text)
            address = resp["address"]
        elif r.status_code == 404:
            raise TestFailure(
                "DisputeCloseVendorTest - FAIL: Address endpoint not found")
        else:
            raise TestFailure(
                "DisputeCloseVendorTest - FAIL: Unknown response")
        self.send_bitcoin_cmd("sendtoaddress", address, generated_coins)
        time.sleep(20)

        # create a profile for charlie
        pro = {"name": "Charlie"}
        api_url = charlie["gateway_url"] + "ob/profile"
        r = requests.post(api_url, data=json.dumps(pro, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "DisputeCloseVendorTest - FAIL: Profile post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "DisputeCloseVendorTest - FAIL: Profile POST failed. Reason: %s",
                resp["reason"])
        time.sleep(4)

        # make charlie a moderator
        with open('testdata/moderation.json') as listing_file:
            moderation_json = json.load(listing_file,
                                        object_pairs_hook=OrderedDict)
        api_url = charlie["gateway_url"] + "ob/moderator"
        r = requests.put(api_url, data=json.dumps(moderation_json, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "DisputeCloseVendorTest - FAIL: Moderator post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "DisputeCloseVendorTest - FAIL: Moderator POST failed. Reason: %s",
                resp["reason"])
        moderatorId = charlie["peerId"]
        time.sleep(4)

        # post profile for alice
        with open('testdata/profile.json') as profile_file:
            profile_json = json.load(profile_file,
                                     object_pairs_hook=OrderedDict)
        api_url = alice["gateway_url"] + "ob/profile"
        requests.post(api_url, data=json.dumps(profile_json, indent=4))

        # post listing to alice
        with open('testdata/listing.json') as listing_file:
            listing_json = json.load(listing_file,
                                     object_pairs_hook=OrderedDict)
        listing_json["metadata"]["pricingCurrency"] = "t" + self.cointype

        listing_json["moderators"] = [moderatorId]
        api_url = alice["gateway_url"] + "ob/listing"
        r = requests.post(api_url, data=json.dumps(listing_json, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "DisputeCloseVendorTest - FAIL: Listing post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "DisputeCloseVendorTest - FAIL: Listing POST failed. Reason: %s",
                resp["reason"])
        resp = json.loads(r.text)
        slug = resp["slug"]
        time.sleep(4)

        # get listing hash
        api_url = alice["gateway_url"] + "ob/listings/" + alice["peerId"]
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "DisputeCloseVendorTest - FAIL: Couldn't get listing index")
        resp = json.loads(r.text)
        listingId = resp[0]["hash"]

        # bob send order
        with open('testdata/order_direct.json') as order_file:
            order_json = json.load(order_file, object_pairs_hook=OrderedDict)
        order_json["items"][0]["listingHash"] = listingId
        order_json["moderator"] = moderatorId
        order_json["paymentCoin"] = "t" + self.cointype
        api_url = bob["gateway_url"] + "ob/purchase"
        r = requests.post(api_url, data=json.dumps(order_json, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "DisputeCloseVendorTest - FAIL: Purchase post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            self.print_logs(alice, "ob.log")
            raise TestFailure(
                "DisputeCloseVendorTest - FAIL: Purchase POST failed. Reason: %s",
                resp["reason"])
        resp = json.loads(r.text)
        orderId = resp["orderId"]
        payment_address = resp["paymentAddress"]
        payment_amount = resp["amount"]

        # check the purchase saved correctly
        api_url = bob["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "DisputeCloseVendorTest - FAIL: Couldn't load order from Bob")
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_PAYMENT":
            raise TestFailure(
                "DisputeCloseVendorTest - FAIL: Bob purchase saved in incorrect state"
            )
        if resp["funded"] == True:
            raise TestFailure(
                "DisputeCloseVendorTest - FAIL: Bob incorrectly saved as funded"
            )

        # check the sale saved correctly
        api_url = alice["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "DisputeCloseVendorTest - FAIL: Couldn't load order from Alice"
            )
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_PAYMENT":
            raise TestFailure(
                "DisputeCloseVendorTest - FAIL: Alice purchase saved in incorrect state"
            )
        if resp["funded"] == True:
            raise TestFailure(
                "DisputeCloseVendorTest - FAIL: Alice incorrectly saved as funded"
            )

        # fund order
        spend = {
            "wallet": self.cointype,
            "address": payment_address,
            "amount": payment_amount,
            "feeLevel": "NORMAL"
        }
        api_url = bob["gateway_url"] + "wallet/spend"
        r = requests.post(api_url, data=json.dumps(spend, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "DisputeCloseVendorTest - FAIL: Spend post endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "DisputeCloseVendorTest - FAIL: Spend POST failed. Reason: %s",
                resp["reason"])
        time.sleep(20)

        # check bob detected payment
        api_url = bob["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "DisputeCloseVendorTest - FAIL: Couldn't load order from Bob")
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_FULFILLMENT":
            raise TestFailure(
                "DisputeCloseVendorTest - FAIL: Bob failed to detect his payment"
            )
        if resp["funded"] == False:
            raise TestFailure(
                "DisputeCloseVendorTest - FAIL: Bob incorrectly saved as unfunded"
            )

        # check alice detected payment
        api_url = alice["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "DisputeCloseVendorTest - FAIL: Couldn't load order from Alice"
            )
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_FULFILLMENT":
            raise TestFailure(
                "DisputeCloseVendorTest - FAIL: Alice failed to detect payment"
            )
        if resp["funded"] == False:
            raise TestFailure(
                "DisputeCloseVendorTest - FAIL: Alice incorrectly saved as unfunded"
            )

        # alice send order fulfillment
        with open('testdata/fulfillment.json') as fulfillment_file:
            fulfillment_json = json.load(fulfillment_file,
                                         object_pairs_hook=OrderedDict)
        fulfillment_json["orderId"] = orderId
        fulfillment_json["slug"] = slug
        api_url = alice["gateway_url"] + "ob/orderfulfillment"
        r = requests.post(api_url, data=json.dumps(fulfillment_json, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "FulfillDirectOnlineTest - FAIL: Fulfillment post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "FulfillDirectOnlineTest - FAIL: Fulfillment POST failed. Reason: %s",
                resp["reason"])
        time.sleep(4)

        # check bob received fulfillment
        api_url = bob["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "FulfillDirectOnlineTest - FAIL: Couldn't load order from Bob")
        resp = json.loads(r.text)
        if resp["state"] != "FULFILLED":
            raise TestFailure(
                "FulfillDirectOnlineTest - FAIL: Bob failed to detect order fulfillment"
            )

        # check alice set fulfillment correctly
        api_url = alice["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "FulfillDirectOnlineTest - FAIL: Couldn't load order from Alice"
            )
        resp = json.loads(r.text)
        if resp["state"] != "FULFILLED":
            raise TestFailure(
                "FulfillDirectOnlineTest - FAIL: Alice failed to order fulfillment"
            )

        # Alice open dispute
        dispute = {"orderId": orderId, "claim": "Bastard ripped me off"}
        api_url = alice["gateway_url"] + "ob/opendispute/"
        r = requests.post(api_url, data=json.dumps(dispute, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "DisputeCloseVendorTest - FAIL: OpenDispute post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "DisputeCloseVendorTest - FAIL: OpenDispute POST failed. Reason: %s",
                resp["reason"])
        time.sleep(4)

        # Alice check dispute opened correctly
        api_url = alice["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "DisputeCloseVendorTest - FAIL: Couldn't load order from Alice"
            )
        resp = json.loads(r.text)
        if resp["state"] != "DISPUTED":
            raise TestFailure(
                "DisputeCloseVendorTest - FAIL: Alice failed to detect his dispute resolution"
            )

        # Bob check dispute opened correctly
        api_url = bob["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "DisputeCloseVendorTest - FAIL: Couldn't load order from Bob")
        resp = json.loads(r.text)
        if resp["state"] != "DISPUTED":
            raise TestFailure(
                "DisputeCloseVendorTest - FAIL: Bob failed to detect the dispute resolution"
            )

        # Charlie check dispute opened correctly
        api_url = charlie["gateway_url"] + "ob/case/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "DisputeCloseVendorTest - FAIL: Couldn't load case from Clarlie"
            )
        resp = json.loads(r.text)
        if resp["state"] != "DISPUTED":
            raise TestFailure(
                "DisputeCloseVendorTest - FAIL: Charlie failed to detect the dispute resolution"
            )

        # Charlie close dispute
        dispute_resolution = {
            "OrderID": orderId,
            "Resolution": "I'm siding with Bob",
            "BuyerPercentage": 0,
            "VendorPercentage": 100
        }
        api_url = charlie["gateway_url"] + "ob/closedispute/"
        r = requests.post(api_url,
                          data=json.dumps(dispute_resolution, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "DisputeCloseVendorTest - FAIL: CloseDispute post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "DisputeCloseVendorTest - FAIL: CloseDispute POST failed. Reason: %s",
                resp["reason"])
        time.sleep(4)

        # Alice check dispute closed correctly
        api_url = alice["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "DisputeCloseVendorTest - FAIL: Couldn't load order from Alice"
            )
        resp = json.loads(r.text)
        if resp["state"] != "DECIDED":
            raise TestFailure(
                "DisputeCloseVendorTest - FAIL: Alice failed to detect the dispute resolution"
            )

        # Bob check dispute closed correctly
        api_url = bob["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "DisputeCloseVendorTest - FAIL: Couldn't load order from Bob")
        resp = json.loads(r.text, object_pairs_hook=OrderedDict)
        if resp["state"] != "DECIDED":
            raise TestFailure(
                "DisputeCloseVendorTest - FAIL: Bob failed to detect the dispute resolution"
            )

        # Charlie check dispute closed correctly
        api_url = charlie["gateway_url"] + "ob/case/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "DisputeCloseVendorTest - FAIL: Couldn't load case from Clarlie"
            )
        resp = json.loads(r.text, object_pairs_hook=OrderedDict)
        if resp["state"] != "RESOLVED":
            raise TestFailure(
                "DisputeCloseVendorTest - FAIL: Charlie failed to detect the dispute resolution"
            )

        # Alice release funds
        release = {
            "OrderID": orderId,
        }
        api_url = alice["gateway_url"] + "ob/releasefunds/"
        r = requests.post(api_url, data=json.dumps(release, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "DisputeCloseVendorTest - FAIL: ReleaseFunds post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "DisputeCloseVendorTest - FAIL: ReleaseFunds POST failed. Reason: %s",
                resp["reason"])
        time.sleep(20)

        self.send_bitcoin_cmd("generate", 1)
        time.sleep(2)

        # Check alice received payout
        api_url = alice["gateway_url"] + "wallet/balance/" + self.cointype
        r = requests.get(api_url)
        if r.status_code == 200:
            resp = json.loads(r.text)
            confirmed = int(resp["confirmed"])
            #unconfirmed = int(resp["unconfirmed"])
            if confirmed <= 0:
                raise TestFailure(
                    "DisputeCloseVendorTest - FAIL: Alice failed to detect dispute payout"
                )
        elif r.status_code == 404:
            raise TestFailure(
                "DisputeCloseVendorTest - FAIL: Receive coins endpoint not found"
            )
        else:
            raise TestFailure(
                "DisputeCloseVendorTest - FAIL: Unknown response")

        # Alice check payout transaction recorded
        api_url = alice["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "DisputeCloseVendorTest - FAIL: Couldn't load order from Alice"
            )
        resp = json.loads(r.text, object_pairs_hook=OrderedDict)
        if len(resp["paymentAddressTransactions"]) != 2:
            raise TestFailure(
                "DisputeCloseVendorTest - FAIL: Alice failed to record payout transaction"
            )
        if resp["state"] != "RESOLVED":
            raise TestFailure(
                "DisputeCloseVendorTest - FAIL: Alice failed to set state to RESOLVED"
            )

        # Bob check payout transaction recorded
        api_url = bob["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "DisputeCloseVendorTest - FAIL: Couldn't load order from Bob")
        resp = json.loads(r.text, object_pairs_hook=OrderedDict)
        if len(resp["paymentAddressTransactions"]) != 2:
            raise TestFailure(
                "DisputeCloseVendorTest - FAIL: Bob failed to record payout transaction"
            )
        if resp["state"] != "RESOLVED":
            raise TestFailure(
                "DisputeCloseVendorTest - FAIL: Bob failed to set state to RESOLVED"
            )

        print("DisputeCloseVendorTest - PASS")
    def run_test(self):
        alice = self.nodes[1]
        bob = self.nodes[2]
        charlie = self.nodes[3]

        # generate some coins and send them to bob
        time.sleep(3)
        api_url = bob["gateway_url"] + "wallet/address/" + self.cointype
        r = requests.get(api_url)
        if r.status_code == 200:
            resp = json.loads(r.text)
            address = resp["address"]
        elif r.status_code == 404:
            raise TestFailure(
                "RejectModeratedOffline - FAIL: Address endpoint not found")
        else:
            raise TestFailure(
                "RejectModeratedOffline - FAIL: Unknown response")
        self.send_bitcoin_cmd("sendtoaddress", address, 10)
        time.sleep(20)

        # create a profile for charlie
        pro = {"name": "Charlie"}
        api_url = charlie["gateway_url"] + "ob/profile"
        r = requests.post(api_url, data=json.dumps(pro, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "PurchaseModeratedOnlineTest - FAIL: Profile post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "PurchaseModeratedOnlineTest - FAIL: Profile POST failed. Reason: %s",
                resp["reason"])
        time.sleep(4)

        # make charlie a moderator
        with open('testdata/moderation.json') as listing_file:
            moderation_json = json.load(listing_file,
                                        object_pairs_hook=OrderedDict)
        api_url = charlie["gateway_url"] + "ob/moderator"
        r = requests.put(api_url, data=json.dumps(moderation_json, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "PurchaseModeratedOnlineTest - FAIL: Moderator post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "PurchaseModeratedOnlineTest - FAIL: Moderator POST failed. Reason: %s",
                resp["reason"])
        moderatorId = charlie["peerId"]
        time.sleep(4)

        # post profile for alice
        with open('testdata/profile.json') as profile_file:
            profile_json = json.load(profile_file,
                                     object_pairs_hook=OrderedDict)
        api_url = alice["gateway_url"] + "ob/profile"
        requests.post(api_url, data=json.dumps(profile_json, indent=4))

        # post listing to alice
        with open('testdata/listing.json') as listing_file:
            listing_json = json.load(listing_file,
                                     object_pairs_hook=OrderedDict)
        listing_json["metadata"]["pricingCurrency"] = "t" + self.cointype
        listing_json["moderators"] = [moderatorId]
        api_url = alice["gateway_url"] + "ob/listing"
        r = requests.post(api_url, data=json.dumps(listing_json, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "RejectModeratedOffline - FAIL: Listing post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "RejectModeratedOffline - FAIL: Listing POST failed. Reason: %s",
                resp["reason"])
        time.sleep(4)

        # get listing hash
        api_url = alice["gateway_url"] + "ob/listings/" + alice["peerId"]
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "RejectModeratedOffline - FAIL: Couldn't get listing index")
        resp = json.loads(r.text)
        listingId = resp[0]["hash"]

        # bob fetch listing to cache
        api_url = bob["gateway_url"] + "ipfs/" + listingId
        requests.get(api_url)

        # shutdown alice
        api_url = alice["gateway_url"] + "ob/shutdown"
        requests.post(api_url, data="")
        time.sleep(4)

        # bob send order
        with open('testdata/order_direct.json') as order_file:
            order_json = json.load(order_file, object_pairs_hook=OrderedDict)
        order_json["items"][0]["listingHash"] = listingId
        order_json["moderator"] = moderatorId
        order_json["paymentCoin"] = "t" + self.cointype
        api_url = bob["gateway_url"] + "ob/purchase"
        r = requests.post(api_url, data=json.dumps(order_json, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "RejectModeratedOffline - FAIL: Purchase post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "RejectModeratedOffline - FAIL: Purchase POST failed. Reason: %s",
                resp["reason"])
        resp = json.loads(r.text)
        orderId = resp["orderId"]
        payment_address = resp["paymentAddress"]
        payment_amount = resp["amount"]
        if resp["vendorOnline"] == True:
            raise TestFailure(
                "RejectModeratedOffline - FAIL: Purchase returned vendor is online"
            )

        # check the purchase saved correctly
        api_url = bob["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "RejectModeratedOffline - FAIL: Couldn't load order from Bob")
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_PAYMENT":
            raise TestFailure(
                "RejectModeratedOffline - FAIL: Bob purchase saved in incorrect state"
            )
        if resp["funded"] == True:
            raise TestFailure(
                "RejectModeratedOffline - FAIL: Bob incorrectly saved as funded"
            )

        # fund order
        spend = {
            "wallet": self.cointype,
            "address": payment_address,
            "amount": payment_amount,
            "feeLevel": "NORMAL"
        }
        api_url = bob["gateway_url"] + "wallet/spend"
        r = requests.post(api_url, data=json.dumps(spend, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "RejectModeratedOffline - FAIL: Spend post endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "RejectModeratedOffline - FAIL: Purchase POST failed. Reason: %s",
                resp["reason"])
        time.sleep(20)

        # check bob detected payment
        api_url = bob["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "RejectModeratedOffline - FAIL: Couldn't load order from Bob")
        resp = json.loads(r.text)
        if len(resp["paymentAddressTransactions"]) <= 0:
            raise TestFailure(
                "RejectModeratedOffline - FAIL: Bob failed to detect his payment"
            )
        if resp["funded"] == False:
            raise TestFailure(
                "RejectModeratedOffline - FAIL: Bob incorrectly saved as unfunded"
            )
        if resp["state"] != "PENDING":
            raise TestFailure(
                "RejectModeratedOffline - FAIL: Bob purchase saved in incorrect state"
            )

        # generate one more block containing this tx
        self.send_bitcoin_cmd("generate", 1)

        # startup alice again
        self.start_node(alice)
        time.sleep(45)

        # alice reject order
        api_url = alice["gateway_url"] + "ob/orderconfirmation"
        oc = {"orderId": orderId, "reject": True}
        r = requests.post(api_url, data=json.dumps(oc, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "RejectModeratedOffline - FAIL: Order confirmation post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "RejectModeratedOffline - FAIL: OrderConfirmation POST failed. Reason: %s",
                resp["reason"])
        time.sleep(20)

        # alice check order rejected correctly
        api_url = alice["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "RejectModeratedOffline - FAIL: Couldn't load order from Alice"
            )
        resp = json.loads(r.text)
        if resp["state"] != "DECLINED":
            raise TestFailure(
                "RejectModeratedOffline - FAIL: Alice failed to save as declined"
            )
        if len(resp["paymentAddressTransactions"]) != 2:
            raise TestFailure(
                "RejectModeratedOffline - FAIL: Alice failed to detect outgoing payment"
            )

        # bob check order rejected correctly
        api_url = bob["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "RejectModeratedOffline - FAIL: Couldn't load order from Bob")
        resp = json.loads(r.text)
        if resp["state"] != "DECLINED":
            raise TestFailure(
                "RejectModeratedOffline - FAIL: Bob failed to save as declined"
            )
        if len(resp["paymentAddressTransactions"]) != 2:
            raise TestFailure(
                "RejectModeratedOffline - FAIL: Bob failed to detect outgoing payment"
            )

        self.send_bitcoin_cmd("generate", 1)
        time.sleep(2)

        # Check the funds moved into bob's wallet
        api_url = bob["gateway_url"] + "wallet/balance/" + self.cointype
        r = requests.get(api_url)
        if r.status_code == 200:
            resp = json.loads(r.text)
            confirmed = int(resp["confirmed"])
            #unconfirmed = int(resp["unconfirmed"])
            if confirmed <= 50 - payment_amount:
                raise TestFailure(
                    "RejectModeratedOffline - FAIL: Bob failed to receive the multisig payout"
                )
        else:
            raise TestFailure(
                "RejectModeratedOffline - FAIL: Failed to query Bob's balance")

        print("RejectModeratedOffline - PASS")
Beispiel #7
0
    def run_test(self):
        alice = self.nodes[0]
        bob = self.nodes[1]

        # configure SMTP notifications
        time.sleep(4)
        api_url = alice["gateway_url"] + "ob/settings"
        smtp = {
            "smtpSettings" : {
                "notifications": True,
                "serverAddress": "0.0.0.0:1025",
                "username": "******",
                "password": "******",
                "senderEmail": "*****@*****.**",
                "recipientEmail": "*****@*****.**"
            }
        }

        r = requests.post(api_url, data=json.dumps(smtp, indent=4))
        if r.status_code == 404:
            raise TestFailure("SMTPTest - FAIL: Settings POST endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure("SMTPTest - FAIL: Settings POST failed. Reason: %s", resp["reason"])
        time.sleep(4)

        # check SMTP settings
        api_url = alice["gateway_url"] + "ob/settings"
        r = requests.get(api_url)
        if r.status_code == 404:
            raise TestFailure("SMTPTest - FAIL: Settings GET endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure("SMTPTest - FAIL: Settings GET failed. Reason: %s", resp["reason"])

        # check notifications
        addr = "0.0.0.0:1025"
        class_name = "test_framework.smtp_server.SMTPTestServer"
        proc = subprocess.Popen(["python", "-m", "smtpd", "-n", "-c", class_name, addr])

        # generate some coins and send them to bob
        time.sleep(4)
        api_url = bob["gateway_url"] + "wallet/address"
        r = requests.get(api_url)
        if r.status_code == 200:
            resp = json.loads(r.text)
            address = resp["address"]
        elif r.status_code == 404:
            raise TestFailure("SMTPTest - FAIL: Address endpoint not found")
        else:
            raise TestFailure("SMTPTest - FAIL: Unknown response")
        self.send_bitcoin_cmd("sendtoaddress", address, 10)
        time.sleep(20)

        # post listing to alice
        with open('testdata/listing.json') as listing_file:
            listing_json = json.load(listing_file, object_pairs_hook=OrderedDict)

        api_url = alice["gateway_url"] + "ob/listing"
        r = requests.post(api_url, data=json.dumps(listing_json, indent=4))
        if r.status_code == 404:
            raise TestFailure("SMTPTest - FAIL: Listing post endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure("SMTPTest - FAIL: Listing POST failed. Reason: %s", resp["reason"])
        time.sleep(4)

        # get listing hash
        api_url = alice["gateway_url"] + "ipns/" + alice["peerId"] + "/listings/index.json"
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure("SMTPTest - FAIL: Couldn't get listing index")
        resp = json.loads(r.text)
        listingId = resp[0]["hash"]

        # bob send order
        with open('testdata/order_direct.json') as order_file:
            order_json = json.load(order_file, object_pairs_hook=OrderedDict)
        order_json["items"][0]["listingHash"] = listingId
        api_url = bob["gateway_url"] + "ob/purchase"
        r = requests.post(api_url, data=json.dumps(order_json, indent=4))
        if r.status_code == 404:
            raise TestFailure("SMTPTest - FAIL: Purchase post endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure("SMTPTest - FAIL: Purchase POST failed. Reason: %s", resp["reason"])
        resp = json.loads(r.text)
        orderId = resp["orderId"]
        payment_address = resp["paymentAddress"]
        payment_amount = resp["amount"]

        # fund order
        spend = {
            "address": payment_address,
            "amount": payment_amount,
            "feeLevel": "NORMAL"
        }
        api_url = bob["gateway_url"] + "wallet/spend"
        r = requests.post(api_url, data=json.dumps(spend, indent=4))
        if r.status_code == 404:
            raise TestFailure("SMTPTest - FAIL: Spend post endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure("SMTPTest - FAIL: Spend POST failed. Reason: %s", resp["reason"])
        time.sleep(20)
        proc.terminate()

        # check notification
        expected = '''From: [email protected]
To: [email protected]
MIME-Version: 1.0
Content-Type: text/html; charset=UTF-8
Subject: [OpenBazaar] Order received

You received an order "Ron Swanson Tshirt".

Order ID: QmNiPgKNq27qQE8fRxMbtDfRcFDEYMH5wDRgdqtqoWBpGg
Buyer: QmS5svqgGwFxwY9W5nXBUh1GJ7x8tqpkYfD4kB3MG7mPRv
Thumbnail: QmNedYJ6WmLhacAL2ozxb4k33Gxd9wmKB7HyoxZCwXid1e
Timestamp: 1487699826
'''
        expected_lines = [e for e in expected.splitlines() if not e.startswith('Timestamp:') and not e.startswith('Order ID:')]
        with open(SMTP_DUMPFILE, 'r') as f:
            res_lines = [l.strip() for l in f.readlines() if not l.startswith('Timestamp') and not l.startswith('Order ID:')]
            if res_lines != expected_lines:
                raise TestFailure("SMTPTest - FAIL: Incorrect mail data received")
        os.remove(SMTP_DUMPFILE)
        print("SMTPTest - PASS")
    def run_test(self):
        alice = self.nodes[1]
        bob = self.nodes[2]
        charlie = self.nodes[3]

        # check bob's initial balance
        time.sleep(4)
        api_url = bob["gateway_url"] + "wallet/balance/T" + self.cointype
        r = requests.get(api_url)
        if r.status_code == 200:
            resp = json.loads(r.text)
            bob_balance = int(resp["confirmed"])
        elif r.status_code == 404:
            raise TestFailure(
                "EthCompleteDisputedTest - FAIL: Address endpoint not found")
        else:
            raise TestFailure(
                "EthCompleteDisputedTest - FAIL: Unknown response")
        time.sleep(20)

        # create a profile for charlie
        pro = {"name": "Charlie"}
        api_url = charlie["gateway_url"] + "ob/profile"
        r = requests.post(api_url, data=json.dumps(pro, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "EthCompleteDisputedTest - FAIL: Profile post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "EthCompleteDisputedTest - FAIL: Profile POST failed. Reason: %s",
                resp["reason"])
        time.sleep(4)

        # make charlie a moderator
        with open('testdata/moderation.json') as listing_file:
            moderation_json = json.load(listing_file,
                                        object_pairs_hook=OrderedDict)
        api_url = charlie["gateway_url"] + "ob/moderator"
        r = requests.put(api_url, data=json.dumps(moderation_json, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "EthCompleteDisputedTest - FAIL: Moderator post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "EthCompleteDisputedTest - FAIL: Moderator POST failed. Reason: %s",
                resp["reason"])
        moderatorId = charlie["peerId"]
        time.sleep(4)

        # post profile for alice
        with open('testdata/profile.json') as profile_file:
            profile_json = json.load(profile_file,
                                     object_pairs_hook=OrderedDict)
        api_url = alice["gateway_url"] + "ob/profile"
        requests.post(api_url, data=json.dumps(profile_json, indent=4))

        # post listing to alice
        with open('testdata/eth_listing.json') as listing_file:
            listing_json = json.load(listing_file,
                                     object_pairs_hook=OrderedDict)
        listing_json["item"]["priceCurrency"]["code"] = "T" + self.cointype
        listing_json["metadata"]["acceptedCurrencies"] = ["T" + self.cointype]
        listing_json["moderators"] = [moderatorId]
        api_url = alice["gateway_url"] + "ob/listing"
        r = requests.post(api_url, data=json.dumps(listing_json, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "EthCompleteDisputedTest - FAIL: Listing post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "EthCompleteDisputedTest - FAIL: Listing POST failed. Reason: %s",
                resp["reason"])
        resp = json.loads(r.text)
        slug = resp["slug"]
        time.sleep(4)

        # get listing hash
        api_url = alice["gateway_url"] + "ob/listings/" + alice["peerId"]
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "EthCompleteDisputedTest - FAIL: Couldn't get listing index")
        resp = json.loads(r.text)
        listingId = resp[0]["hash"]

        # bob send order
        with open('testdata/order_direct.json') as order_file:
            order_json = json.load(order_file, object_pairs_hook=OrderedDict)
        order_json["items"][0]["listingHash"] = listingId
        order_json["moderator"] = moderatorId
        order_json["paymentCoin"] = "T" + self.cointype
        api_url = bob["gateway_url"] + "ob/purchase"
        r = requests.post(api_url, data=json.dumps(order_json, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "EthCompleteDisputedTest - FAIL: Purchase post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            self.print_logs(alice, "ob.log")
            raise TestFailure(
                "EthCompleteDisputedTest - FAIL: Purchase POST failed. Reason: %s",
                resp["reason"])
        resp = json.loads(r.text)
        orderId = resp["orderId"]
        payment_address = resp["paymentAddress"]
        payment_amount = resp["amount"]

        # check the purchase saved correctly
        api_url = bob["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "EthCompleteDisputedTest - FAIL: Couldn't load order from Bob")
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_PAYMENT":
            raise TestFailure(
                "EthCompleteDisputedTest - FAIL: Bob purchase saved in incorrect state"
            )
        if resp["funded"] == True:
            raise TestFailure(
                "EthCompleteDisputedTest - FAIL: Bob incorrectly saved as funded"
            )

        # check the sale saved correctly
        api_url = alice["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "EthCompleteDisputedTest - FAIL: Couldn't load order from Alice"
            )
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_PAYMENT":
            raise TestFailure(
                "EthCompleteDisputedTest - FAIL: Alice purchase saved in incorrect state"
            )
        if resp["funded"] == True:
            raise TestFailure(
                "EthCompleteDisputedTest - FAIL: Alice incorrectly saved as funded"
            )

        # fund order
        spend = {
            "currencyCode": "T" + self.cointype,
            "address": payment_address,
            "amount": payment_amount["amount"],
            "feeLevel": "NORMAL",
            "requireAssociateOrder": True,
            "orderID": orderId
        }
        api_url = bob["gateway_url"] + "ob/orderspend"
        r = requests.post(api_url, data=json.dumps(spend, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "EthCompleteDisputedTest - FAIL: Spend post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "EthCompleteDisputedTest - FAIL: Spend POST failed. Reason: %s",
                resp["reason"])
        time.sleep(20)

        # check bob detected payment
        api_url = bob["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "EthCompleteDisputedTest - FAIL: Couldn't load order from Bob")
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_FULFILLMENT":
            raise TestFailure(
                "EthCompleteDisputedTest - FAIL: Bob failed to detect his payment"
            )
        if resp["funded"] == False:
            raise TestFailure(
                "EthCompleteDisputedTest - FAIL: Bob incorrectly saved as unfunded"
            )

        # check alice detected payment
        api_url = alice["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "EthCompleteDisputedTest - FAIL: Couldn't load order from Alice"
            )
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_FULFILLMENT":
            raise TestFailure(
                "EthCompleteDisputedTest - FAIL: Alice failed to detect payment"
            )
        if resp["funded"] == False:
            raise TestFailure(
                "EthCompleteDisputedTest - FAIL: Alice incorrectly saved as unfunded"
            )

        # alice send order fulfillment
        with open('testdata/fulfillment.json') as fulfillment_file:
            fulfillment_json = json.load(fulfillment_file,
                                         object_pairs_hook=OrderedDict)
        fulfillment_json["orderId"] = orderId
        fulfillment_json["slug"] = slug
        api_url = alice["gateway_url"] + "ob/orderfulfillment"
        r = requests.post(api_url, data=json.dumps(fulfillment_json, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "EthCompleteDisputedTest - FAIL: Fulfillment post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "EthCompleteDisputedTest - FAIL: Fulfillment POST failed. Reason: %s",
                resp["reason"])
        time.sleep(4)

        # Bob open dispute
        dispute = {"orderId": orderId, "claim": "Bastard ripped me off"}
        api_url = bob["gateway_url"] + "ob/opendispute/"
        r = requests.post(api_url, data=json.dumps(dispute, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "EthCompleteDisputedTest - FAIL: OpenDispute post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "EthCompleteDisputedTest - FAIL: OpenDispute POST failed. Reason: %s",
                resp["reason"])
        time.sleep(4)

        # Bob check dispute opened correctly
        api_url = bob["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "EthCompleteDisputedTest - FAIL: Couldn't load order from Bob")
        resp = json.loads(r.text)
        if resp["state"] != "DISPUTED":
            raise TestFailure(
                "EthCompleteDisputedTest - FAIL: Bob failed to detect his dispute"
            )

        # Alice check dispute opened correctly
        api_url = alice["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "EthCompleteDisputedTest - FAIL: Couldn't load order from Alice"
            )
        resp = json.loads(r.text)
        if resp["state"] != "DISPUTED":
            raise TestFailure(
                "EthCompleteDisputedTest - FAIL: Alice failed to detect the dispute"
            )

        # Charlie check dispute opened correctly
        api_url = charlie["gateway_url"] + "ob/case/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "EthCompleteDisputedTest - FAIL: Couldn't load case from Clarlie"
            )
        resp = json.loads(r.text, object_pairs_hook=OrderedDict)
        if resp["state"] != "DISPUTED":
            raise TestFailure(
                "EthCompleteDisputedTest - FAIL: Charlie failed to detect the dispute"
            )

        # Charlie close dispute
        dispute_resolution = {
            "OrderID": orderId,
            "Resolution": "I'm siding with Bob",
            "BuyerPercentage": 100,
            "VendorPercentage": 0
        }
        api_url = charlie["gateway_url"] + "ob/closedispute/"
        r = requests.post(api_url,
                          data=json.dumps(dispute_resolution, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "EthCompleteDisputedTest - FAIL: CloseDispute post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "EthCompleteDisputedTest - FAIL: CloseDispute POST failed. Reason: %s",
                resp["reason"])
        time.sleep(4)

        # Alice check dispute closed correctly
        api_url = alice["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "EthCompleteDisputedTest - FAIL: Couldn't load order from Alice"
            )
        resp = json.loads(r.text)
        if resp["state"] != "DECIDED":
            self.print_logs(alice, "ob.log")
            raise TestFailure(
                "EthCompleteDisputedTest - FAIL: Alice failed to detect the dispute resolution"
            )

        # Bob check dispute closed correctly
        api_url = bob["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "EthCompleteDisputedTest - FAIL: Couldn't load order from Bob")
        resp = json.loads(r.text, object_pairs_hook=OrderedDict)
        if resp["state"] != "DECIDED":
            raise TestFailure(
                "EthCompleteDisputedTest - FAIL: Bob failed to detect the dispute resolution"
            )

        # Charlie check dispute closed correctly
        api_url = charlie["gateway_url"] + "ob/case/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "EthCompleteDisputedTest - FAIL: Couldn't load case from Charlie"
            )
        resp = json.loads(r.text, object_pairs_hook=OrderedDict)
        if resp["state"] != "RESOLVED":
            raise TestFailure(
                "EthCompleteDisputedTest - FAIL: Charlie failed to detect the dispute resolution"
            )

        # Bob release funds
        release = {
            "OrderID": orderId,
        }
        api_url = bob["gateway_url"] + "ob/releasefunds/"
        r = requests.post(api_url, data=json.dumps(release, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "EthCompleteDisputedTest - FAIL: ReleaseFunds post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "EthCompleteDisputedTest - FAIL: ReleaseFunds POST failed. Reason: %s",
                resp["reason"])
        time.sleep(20)

        time.sleep(5)

        # Check bob received payout
        api_url = bob["gateway_url"] + "wallet/balance/T" + self.cointype
        r = requests.get(api_url)
        if r.status_code == 200:
            resp = json.loads(r.text)
            confirmed = int(resp["confirmed"])
            #unconfirmed = int(resp["unconfirmed"])
            #if confirmed <= (bob_balance) - int(payment_amount["amount"]):
            #    raise TestFailure("EthCompleteDisputedTest - FAIL: Bob failed to detect dispute payout")
        elif r.status_code == 404:
            raise TestFailure(
                "EthCompleteDisputedTest - FAIL: Receive coins endpoint not found"
            )
        else:
            raise TestFailure(
                "EthCompleteDisputedTest - FAIL: Unknown response")

        # Bob check payout transaction recorded
        api_url = bob["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "EthCompleteDisputedTest - FAIL: Couldn't load order from Bob")
        resp = json.loads(r.text, object_pairs_hook=OrderedDict)
        if len(resp["paymentAddressTransactions"]) != 2:
            raise TestFailure(
                "EthCompleteDisputedTest - FAIL: Bob failed to record payout transaction"
            )
        if resp["state"] != "RESOLVED":
            raise TestFailure(
                "EthCompleteDisputedTest - FAIL: Bob failed to set state to RESOLVED"
            )

        # Alice check payout transaction recorded
        api_url = alice["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "EthCompleteDisputedTest - FAIL: Couldn't load order from Alice"
            )
        resp = json.loads(r.text, object_pairs_hook=OrderedDict)
        if len(resp["paymentAddressTransactions"]) != 2:
            raise TestFailure(
                "EthCompleteDisputedTest - FAIL: Alice failed to record payout transaction"
            )
        if resp["state"] != "RESOLVED":
            raise TestFailure(
                "EthCompleteDisputedTest - FAIL: Alice failed to set state to RESOLVED"
            )

        # bob send order completion
        oc = {
            "orderId":
            orderId,
            "ratings": [{
                "slug": slug,
                "overall": 4,
                "quality": 5,
                "description": 5,
                "customerService": 4,
                "deliverySpeed": 3,
                "Review": "I love it!"
            }]
        }
        api_url = bob["gateway_url"] + "ob/ordercompletion"
        r = requests.post(api_url, data=json.dumps(oc, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "EthCompleteDisputedTest - FAIL: Completion post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "EthCompleteDisputedTest - FAIL: Completion POST failed. Reason: %s",
                resp["reason"])
        time.sleep(4)

        # check alice received completion
        api_url = alice["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "EthCompleteDisputedTest - FAIL: Couldn't load order from Alice"
            )
        resp = json.loads(r.text)
        if resp["state"] != "COMPLETED":
            raise TestFailure(
                "EthCompleteDisputedTest - FAIL: Alice failed to detect order completion"
            )

        # check bob set completion correctly
        api_url = bob["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "EthCompleteDisputedTest - FAIL: Couldn't load order from Bob")
        resp = json.loads(r.text)
        if resp["state"] != "COMPLETED":
            raise TestFailure(
                "EthCompleteDisputedTest - FAIL: Bob failed to order completion"
            )

        print("EthCompleteDisputedTest - PASS")
    def run_test(self):
        alice = self.nodes[1]
        bob = self.nodes[2]

        # post profile for alice
        with open('testdata/profile.json') as profile_file:
            profile_json = json.load(profile_file, object_pairs_hook=OrderedDict)
        api_url = alice["gateway_url"] + "ob/profile"
        requests.post(api_url, data=json.dumps(profile_json, indent=4))

        # configure SMTP notifications
        time.sleep(4)
        api_url = alice["gateway_url"] + "ob/settings"
        smtp = {
            "smtpSettings" : {
                "notifications": True,
                "serverAddress": "0.0.0.0:1024",
                "username": "******",
                "password": "******",
                "senderEmail": "*****@*****.**",
                "recipientEmail": "*****@*****.**"
            }
        }

        r = requests.post(api_url, data=json.dumps(smtp, indent=4))
        if r.status_code == 404:
            raise TestFailure("SMTPTest - FAIL: Settings POST endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure("SMTPTest - FAIL: Settings POST failed. Reason: %s", resp["reason"])
        time.sleep(4)

        # check SMTP settings
        api_url = alice["gateway_url"] + "ob/settings"
        r = requests.get(api_url)
        if r.status_code == 404:
            raise TestFailure("SMTPTest - FAIL: Settings GET endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure("SMTPTest - FAIL: Settings GET failed. Reason: %s", resp["reason"])

        # check notifications
        addr = "0.0.0.0:1024"
        class_name = "test_framework.smtp_server.SMTPTestServer"
        proc = subprocess.Popen(["python", "-m", "smtpd", "-n", "-c", class_name, addr])

        # generate some coins and send them to bob
        time.sleep(4)
        api_url = bob["gateway_url"] + "wallet/address/" + self.cointype
        r = requests.get(api_url)
        if r.status_code == 200:
            resp = json.loads(r.text)
            address = resp["address"]
        elif r.status_code == 404:
            raise TestFailure("SMTPTest - FAIL: Address endpoint not found")
        else:
            raise TestFailure("SMTPTest - FAIL: Unknown response")
        self.send_bitcoin_cmd("sendtoaddress", address, 10)
        time.sleep(20)

        # post listing to alice
        with open('testdata/listing.json') as listing_file:
            listing_json = json.load(listing_file, object_pairs_hook=OrderedDict)
        listing_json["item"]["priceCurrency"]["code"] = "t" + self.cointype

        api_url = alice["gateway_url"] + "ob/listing"
        r = requests.post(api_url, data=json.dumps(listing_json, indent=4))
        if r.status_code == 404:
            raise TestFailure("SMTPTest - FAIL: Listing post endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure("SMTPTest - FAIL: Listing POST failed. Reason: %s", resp["reason"])
        time.sleep(4)

        # get listing hash
        api_url = alice["gateway_url"] + "ipns/" + alice["peerId"] + "/listings.json"
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure("SMTPTest - FAIL: Couldn't get listing index")
        resp = json.loads(r.text)
        listingId = resp[0]["hash"]

        # bob send order
        with open('testdata/order_direct.json') as order_file:
            order_json = json.load(order_file, object_pairs_hook=OrderedDict)
        order_json["items"][0]["listingHash"] = listingId
        order_json["paymentCoin"] = "t" + self.cointype
        api_url = bob["gateway_url"] + "ob/purchase"
        r = requests.post(api_url, data=json.dumps(order_json, indent=4))
        if r.status_code == 404:
            raise TestFailure("SMTPTest - FAIL: Purchase post endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure("SMTPTest - FAIL: Purchase POST failed. Reason: %s", resp["reason"])
        resp = json.loads(r.text)
        orderId = resp["orderId"]
        payment_address = resp["paymentAddress"]
        payment_amount = resp["amount"]

        # fund order
        spend = {
            "currencyCode": "T" + self.cointype,
            "address": payment_address,
            "amount": payment_amount["amount"],
            "feeLevel": "NORMAL",
            "requireAssociateOrder": False
        }
        api_url = bob["gateway_url"] + "wallet/spend"
        r = requests.post(api_url, data=json.dumps(spend, indent=4))
        if r.status_code == 404:
            raise TestFailure("SMTPTest - FAIL: Spend post endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure("SMTPTest - FAIL: Spend POST failed. Reason: %s", resp["reason"])
        time.sleep(20)
        proc.terminate()

        # check notification
        expected = '''From: [email protected]
To: [email protected]
MIME-Version: 1.0
Content-Type: text/html; charset=UTF-8
Subject: [OpenBazaar] Order received

You received an order "Ron Swanson Tshirt".

Order ID: QmNiPgKNq27qQE8fRxMbtDfRcFDEYMH5wDRgdqtqoWBpGg
Buyer: Qmd5qDpcYkHCmkj9pMXU9TKBqEDWgEmtoHD5xjdJgumaHg
Thumbnail: QmXSEqXLCzpCByJU4wqbJ37TcBEj77FKMUWUP1qLh56847
Timestamp: 1487699826
'''
        expected_lines = [e for e in expected.splitlines() if not e.startswith('Timestamp:') and not e.startswith('Order ID:')]
        with open(SMTP_DUMPFILE, 'r') as f:
            res_lines = [l.strip() for l in f.readlines() if not l.startswith('Timestamp') and not l.startswith('Order ID:')]
            if res_lines != expected_lines:
                os.remove(SMTP_DUMPFILE)
                raise TestFailure("SMTPTest - FAIL: Incorrect mail data received")
        os.remove(SMTP_DUMPFILE)
        print("SMTPTest - PASS")
Beispiel #10
0
    def run_test(self):
        alice = self.nodes[1]
        bob = self.nodes[2]

        # post profile for alice
        with open('testdata/profile.json') as profile_file:
            profile_json = json.load(profile_file,
                                     object_pairs_hook=OrderedDict)
        api_url = alice["gateway_url"] + "ob/profile"
        requests.post(api_url, data=json.dumps(profile_json, indent=4))

        # post listing to alice
        with open('testdata/eth_listing.json') as listing_file:
            listing_json = json.load(listing_file,
                                     object_pairs_hook=OrderedDict)
        listing_json["item"]["priceCurrency"]["code"] = "T" + self.cointype
        listing_json["metadata"]["acceptedCurrencies"] = ["T" + self.cointype]

        api_url = alice["gateway_url"] + "ob/listing"
        r = requests.post(api_url, data=json.dumps(listing_json, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "EthPurchaseOfflineErrorTest - FAIL: Listing post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "EthPurchaseOfflineErrorTest - FAIL: Listing POST failed. Reason: %s",
                resp["reason"])
        time.sleep(20)

        # get listing hash
        api_url = alice["gateway_url"] + "ob/listings/" + alice["peerId"]
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "EthPurchaseOfflineErrorTest - FAIL: Couldn't get listing index"
            )
        resp = json.loads(r.text)
        listingId = resp[0]["hash"]

        # bob fetch listing to cache
        api_url = bob["gateway_url"] + "ipfs/" + listingId
        requests.get(api_url)

        # generate some coins and send them to bob
        api_url = bob["gateway_url"] + "wallet/address/T" + self.cointype
        r = requests.get(api_url)
        if r.status_code == 200:
            resp = json.loads(r.text)
            address = resp["address"]
        elif r.status_code == 404:
            raise TestFailure(
                "EthPurchaseOfflineErrorTest - FAIL: Address endpoint not found"
            )
        else:
            raise TestFailure(
                "EthPurchaseOfflineErrorTest - FAIL: Unknown response")
        time.sleep(3)

        # shutdown alice
        api_url = alice["gateway_url"] + "ob/shutdown"
        requests.post(api_url, data="")
        time.sleep(30)

        # bob send order
        with open('testdata/order_direct.json') as order_file:
            order_json = json.load(order_file, object_pairs_hook=OrderedDict)
        order_json["items"][0]["listingHash"] = listingId

        # set empty shipping address to trigger error
        order_json["address"] = ""
        order_json["paymentCoin"] = "T" + self.cointype

        api_url = bob["gateway_url"] + "ob/purchase"
        r = requests.post(api_url, data=json.dumps(order_json, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "EthPurchaseOfflineErrorTest - FAIL: Purchase post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "EthPurchaseOfflineErrorTest - FAIL: Purchase POST failed. Reason: %s",
                resp["reason"])
        resp = json.loads(r.text)
        orderId = resp["orderId"]
        payment_address = resp["paymentAddress"]
        payment_amount = resp["amount"]
        if resp["vendorOnline"] == True:
            raise TestFailure(
                "EthPurchaseOfflineErrorTest - FAIL: Purchase returned vendor is online"
            )

        # check the purchase saved correctly
        api_url = bob["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "EthPurchaseOfflineErrorTest - FAIL: Couldn't load order from Bob"
            )
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_PAYMENT":
            raise TestFailure(
                "EthPurchaseOfflineErrorTest - FAIL: Bob purchase saved in incorrect state"
            )
        if resp["funded"] == True:
            raise TestFailure(
                "EthPurchaseOfflineErrorTest - FAIL: Bob incorrectly saved as funded"
            )

        # startup alice again
        self.start_node(alice)
        time.sleep(45)

        # check alice detected processing error
        api_url = alice["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "EthPurchaseOfflineErrorTest - FAIL: Couldn't load order from Alice"
            )
        resp = json.loads(r.text)
        if resp["state"] != "PROCESSING_ERROR":
            raise TestFailure(
                "EthPurchaseOfflineErrorTest - FAIL: Alice failed to detect processing error"
            )

        # check bob detected error message from alice
        api_url = bob["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "PurchaseDirectOnlineTest - FAIL: Couldn't load order from Bob"
            )
        resp = json.loads(r.text)
        if resp["state"] != "PROCESSING_ERROR":
            raise TestFailure(
                "PurchaseDirectOnlineTest - FAIL: Bob failed to set state correctly"
            )

        print("EthPurchaseOfflineErrorTest - PASS")
Beispiel #11
0
    def run_test(self):
        vendor = self.nodes[1]
        buyer = self.nodes[2]

        # generate some coins and send them to buyer
        api_url = buyer["gateway_url"] + "wallet/address/" + self.cointype
        r = requests.get(api_url)
        if r.status_code == 200:
            resp = json.loads(r.text)
            address = resp["address"]
        elif r.status_code == 404:
            raise TestFailure(
                "PurchaseDirectOnlineTest - FAIL: Address endpoint not found")
        else:
            raise TestFailure(
                "PurchaseDirectOnlineTest - FAIL: Unknown response")
        self.send_bitcoin_cmd("sendtoaddress", address, 10)
        time.sleep(20)

        # post profile for vendor
        with open('testdata/profile.json') as profile_file:
            profile_json = json.load(profile_file,
                                     object_pairs_hook=OrderedDict)
        api_url = vendor["gateway_url"] + "ob/profile"
        requests.post(api_url, data=json.dumps(profile_json, indent=4))

        # post listing to vendor
        with open('testdata/listing.json') as listing_file:
            listing_json = json.load(listing_file,
                                     object_pairs_hook=OrderedDict)
        listing_json["metadata"]["pricingCurrency"] = "t" + self.cointype

        api_url = vendor["gateway_url"] + "ob/listing"
        r = requests.post(api_url, data=json.dumps(listing_json, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "PurchaseDirectOnlineTest - FAIL: Listing post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "PurchaseDirectOnlineTest - FAIL: Listing POST failed. Reason: %s",
                resp["reason"])
        time.sleep(4)

        # get listing hash
        api_url = vendor["gateway_url"] + "ipns/" + vendor[
            "peerId"] + "/listings.json"
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "PurchaseDirectOnlineTest - FAIL: Couldn't get listing index")
        resp = json.loads(r.text)
        listingId = resp[0]["hash"]

        # buyer send order
        with open('testdata/order_direct.json') as order_file:
            order_json = json.load(order_file, object_pairs_hook=OrderedDict)
        order_json["items"][0]["listingHash"] = listingId
        order_json["paymentCoin"] = "t" + self.cointype
        api_url = buyer["gateway_url"] + "ob/purchase"
        r = requests.post(api_url, data=json.dumps(order_json, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "PurchaseDirectOnlineTest - FAIL: Purchase post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "PurchaseDirectOnlineTest - FAIL: Purchase POST failed. Reason: %s",
                resp["reason"])
        resp = json.loads(r.text)
        orderId = resp["orderId"]
        payment_address = resp["paymentAddress"]
        payment_amount = resp["amount"]

        # check the purchase saved correctly
        api_url = buyer["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "PurchaseDirectOnlineTest - FAIL: Couldn't load order from Buyer"
            )
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_PAYMENT":
            raise TestFailure(
                "PurchaseDirectOnlineTest - FAIL: Buyer purchase saved in incorrect state"
            )
        if resp["funded"] == True:
            raise TestFailure(
                "PurchaseDirectOnlineTest - FAIL: Buyer incorrectly saved as funded"
            )

        # check the sale saved correctly
        api_url = vendor["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "PurchaseDirectOnlineTest - FAIL: Couldn't load order from Vendor"
            )
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_PAYMENT":
            raise TestFailure(
                "PurchaseDirectOnlineTest - FAIL: Vendor purchase saved in incorrect state"
            )
        if resp["funded"] == True:
            raise TestFailure(
                "PurchaseDirectOnlineTest - FAIL: Vendor incorrectly saved as funded"
            )

        # fund order
        spend = {
            "wallet": self.cointype,
            "address": payment_address,
            "amount": payment_amount,
            "feeLevel": "NORMAL"
        }
        api_url = buyer["gateway_url"] + "wallet/spend"
        r = requests.post(api_url, data=json.dumps(spend, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "PurchaseDirectOnlineTest - FAIL: Spend post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "PurchaseDirectOnlineTest - FAIL: Spend POST failed. Reason: %s",
                resp["reason"])
        time.sleep(20)

        # check buyer detected payment
        api_url = buyer["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "PurchaseDirectOnlineTest - FAIL: Couldn't load order from Buyer"
            )
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_FULFILLMENT":
            raise TestFailure(
                "PurchaseDirectOnlineTest - FAIL: Buyer failed to detect his payment"
            )
        if resp["funded"] == False:
            raise TestFailure(
                "PurchaseDirectOnlineTest - FAIL: Buyer incorrectly saved as unfunded"
            )

        # check vendor detected payment
        api_url = vendor["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "PurchaseDirectOnlineTest - FAIL: Couldn't load order from Vendor"
            )
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_FULFILLMENT":
            raise TestFailure(
                "PurchaseDirectOnlineTest - FAIL: Vendor failed to detect payment"
            )
        if resp["funded"] == False:
            raise TestFailure(
                "PurchaseDirectOnlineTest - FAIL: Vendor incorrectly saved as unfunded"
            )

        # buyer send order
        with open(
                'testdata/order_direct_too_much_quantity.json') as order_file:
            order_json = json.load(order_file, object_pairs_hook=OrderedDict)

        order_json["items"][0]["listingHash"] = listingId
        order_json["paymentCoin"] = "t" + self.cointype
        api_url = buyer["gateway_url"] + "ob/purchase"
        r = requests.post(api_url, data=json.dumps(order_json, indent=4))
        resp = json.loads(r.text)
        if r.status_code == 200:
            raise TestFailure(
                "PurchaseDirectOnlineTest - FAIL: Purchase POST should have failed failed."
            )
        if resp["reason"] != "not enough inventory":
            raise TestFailure(
                "PurchaseDirectOnlineTest - FAIL: Purchase POST failed with incorrect reason: %s",
                resp["reason"])
        if resp["code"] != "ERR_INSUFFICIENT_INVENTORY":
            raise TestFailure(
                "PurchaseDirectOnlineTest - FAIL: Purchase POST failed with incorrect code: %s",
                resp["code"])
        if resp["remainingInventory"] != 6:
            raise TestFailure(
                "PurchaseDirectOnlineTest - FAIL: Purchase POST failed with incorrect remainingInventory: %d",
                resp["remainingInventory"])

        print("PurchaseDirectOnlineTest - PASS")
    def run_test(self):
        alice = self.nodes[0]
        bob = self.nodes[1]

        # generate some coins and send them to bob
        time.sleep(4)
        api_url = bob["gateway_url"] + "wallet/address"
        r = requests.get(api_url)
        if r.status_code == 200:
            resp = json.loads(r.text)
            address = resp["address"]
        elif r.status_code == 404:
            raise TestFailure(
                "CancelDirectOfflineTest - FAIL: Address endpoint not found")
        else:
            raise TestFailure(
                "CancelDirectOfflineTest - FAIL: Unknown response")
        self.send_bitcoin_cmd("sendtoaddress", address, 10)
        time.sleep(20)

        # post listing to alice
        with open('testdata/listing.json') as listing_file:
            listing_json = json.load(listing_file,
                                     object_pairs_hook=OrderedDict)
        api_url = alice["gateway_url"] + "ob/listing"
        r = requests.post(api_url, data=json.dumps(listing_json, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "CancelDirectOfflineTest - FAIL: Listing post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "CancelDirectOfflineTest - FAIL: Listing POST failed. Reason: %s",
                resp["reason"])
        time.sleep(4)

        # get listing hash
        api_url = alice["gateway_url"] + "ipns/" + alice[
            "peerId"] + "/listings/index.json"
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "CancelDirectOfflineTest - FAIL: Couldn't get listing index")
        resp = json.loads(r.text)
        listingId = resp[0]["hash"]

        # bob fetch listing to cache
        api_url = bob["gateway_url"] + "ipfs/" + listingId
        requests.get(api_url)

        # shutdown alice
        api_url = alice["gateway_url"] + "ob/shutdown"
        requests.post(api_url, data="")
        time.sleep(4)

        # bob send order
        with open('testdata/order_direct.json') as order_file:
            order_json = json.load(order_file, object_pairs_hook=OrderedDict)
        order_json["items"][0]["listingHash"] = listingId
        api_url = bob["gateway_url"] + "ob/purchase"
        r = requests.post(api_url, data=json.dumps(order_json, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "CancelDirectOfflineTest - FAIL: Purchase post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "CancelDirectOfflineTest - FAIL: Purchase POST failed. Reason: %s",
                resp["reason"])
        resp = json.loads(r.text)
        orderId = resp["orderId"]
        payment_address = resp["paymentAddress"]
        payment_amount = resp["amount"]
        if resp["vendorOnline"] == True:
            raise TestFailure(
                "CancelDirectOfflineTest - FAIL: Purchase returned vendor is online"
            )

        # check the purchase saved correctly
        api_url = bob["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "CancelDirectOfflineTest - FAIL: Couldn't load order from Bob")
        resp = json.loads(r.text)
        if resp["state"] != "PENDING":
            raise TestFailure(
                "CancelDirectOfflineTest - FAIL: Bob purchase saved in incorrect state"
            )
        if resp["funded"] == True:
            raise TestFailure(
                "CancelDirectOfflineTest - FAIL: Bob incorrectly saved as funded"
            )

        # fund order
        spend = {
            "address": payment_address,
            "amount": payment_amount,
            "feeLevel": "NORMAL"
        }
        api_url = bob["gateway_url"] + "wallet/spend"
        r = requests.post(api_url, data=json.dumps(spend, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "CancelDirectOfflineTest - FAIL: Spend post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "CancelDirectOfflineTest - FAIL: Purchase POST failed. Reason: %s",
                resp["reason"])
        time.sleep(20)

        # check bob detected payment
        api_url = bob["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "CancelDirectOfflineTest - FAIL: Couldn't load order from Bob")
        resp = json.loads(r.text)
        if len(resp["transactions"]) <= 0:
            raise TestFailure(
                "CancelDirectOfflineTest - FAIL: Bob failed to detect his payment"
            )
        if resp["funded"] == False:
            raise TestFailure(
                "CancelDirectOfflineTest - FAIL: Bob incorrectly saved as unfunded"
            )

        # bob cancel order
        api_url = bob["gateway_url"] + "ob/ordercancel"
        cancel = {"orderId": orderId}
        r = requests.post(api_url, data=json.dumps(cancel, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "CancelDirectOfflineTest - FAIL: Spend post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "CancelDirectOfflineTest - FAIL: Cancel POST failed. Reason: %s",
                resp["reason"])
        time.sleep(4)

        # bob check order canceled correctly
        api_url = bob["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "CancelDirectOfflineTest - FAIL: Couldn't load order from Bob")
        resp = json.loads(r.text)
        if resp["state"] != "CANCELED":
            raise TestFailure(
                "CancelDirectOfflineTest - FAIL: Bob failed to save as canceled"
            )
        if len(resp["transactions"]) != 2:
            raise TestFailure(
                "CancelDirectOfflineTest - FAIL: Bob failed to detect outgoing payment"
            )

        # startup alice again
        self.start_node(alice)
        time.sleep(45)

        # check alice detected order
        api_url = alice["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            self.print_logs(alice, "ob.log")
            raise TestFailure(
                "CancelDirectOfflineTest - FAIL: Couldn't load order from Alice %s",
                r.status_code)
        resp = json.loads(r.text)
        if resp["state"] != "CANCELED":
            raise TestFailure(
                "CancelDirectOfflineTest - FAIL: Alice failed to detect order cancellation"
            )

        # Check the funds moved into bob's wallet
        api_url = bob["gateway_url"] + "wallet/balance"
        r = requests.get(api_url)
        if r.status_code == 200:
            resp = json.loads(r.text)
            confirmed = int(resp["confirmed"])
            unconfirmed = int(resp["unconfirmed"])
            if confirmed + unconfirmed <= 50 - payment_amount:
                raise TestFailure(
                    "CancelDirectOfflineTest - FAIL: Bob failed to receive the multisig payout"
                )
        else:
            raise TestFailure(
                "CancelDirectOfflineTest - FAIL: Failed to query Bob's balance"
            )

        print("CancelDirectOfflineTest - PASS")
Beispiel #13
0
    def run_test(self):
        vendor = self.nodes[0]
        browser = self.nodes[1]

        currency = "tbtc"

        # no listings POSTed
        api_url = vendor["gateway_url"] + "ob/listings"
        r = requests.get(api_url)
        if r.status_code == 200:
            if len(json.loads(r.text)) == 0:
                pass
            else:
                raise TestFailure(
                    "ListingsTest - FAIL: No listings should be returned")
        elif r.status_code == 404:
            raise TestFailure(
                "ListingsTest - FAIL: Listings get endpoint not found")
        else:
            resp = json.loads(r.text)
            raise TestFailure(
                "ListingsTest - FAIL: Listings GET failed. Reason: %s",
                resp["reason"])

        # POST listing
        with open('testdata/listing.json') as listing_file:
            ljson = json.load(listing_file, object_pairs_hook=OrderedDict)
        if self.bitcoincash:
            ljson["metadata"]["pricingCurrency"] = "tbch"
            currency = "tbch"
        api_url = vendor["gateway_url"] + "ob/listing"
        r = requests.post(api_url, data=json.dumps(ljson, indent=4))
        if r.status_code == 200:
            pass
        elif r.status_code == 404:
            raise TestFailure(
                "ListingsTest - FAIL: Listing post endpoint not found")
        else:
            resp = json.loads(r.text)
            raise TestFailure(
                "ListingsTest - FAIL: Listing POST failed. Reason: %s",
                resp["reason"])

        # one listing POSTed and index returning correct data
        api_url = vendor["gateway_url"] + "ob/listings"
        r = requests.get(api_url)
        if r.status_code == 404:
            raise TestFailure(
                "ListingsTest - FAIL: Listings get endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "ListingsTest - FAIL: Listings GET failed. Reason: %s",
                resp["reason"])

        resp = json.loads(r.text)
        if len(resp) != 1:
            raise TestFailure(
                "ListingsTest - FAIL: One listing should be returned")

        listing = resp[0]
        if listing["acceptedCurrencies"] != [currency]:
            raise TestFailure(
                "ListingsTest - FAIL: Listing should have acceptedCurrences")

        # listing show endpoint returning correct data
        slug = listing["slug"]
        api_url = vendor["gateway_url"] + "ob/listing/" + slug
        r = requests.get(api_url)
        if r.status_code == 404:
            raise TestFailure(
                "ListingsTest - FAIL: Listings get endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "ListingsTest - FAIL: Listings GET failed. Reason: %s",
                resp["reason"])

        resp = json.loads(r.text)
        if resp["listing"]["metadata"]["acceptedCurrencies"] != [
                currency.upper()
        ]:
            raise TestFailure(
                "ListingsTest - FAIL: Listing should have acceptedCurrences in metadata"
            )

        # check vendor's index from another node
        api_url = browser["gateway_url"] + "ob/listings/" + vendor["peerId"]
        r = requests.get(api_url)
        if r.status_code == 404:
            raise TestFailure(
                "ListingsTest - FAIL: Listings get endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "ListingsTest - FAIL: Listings GET failed. Reason: %s",
                resp["reason"])
        resp = json.loads(r.text)
        if len(resp) != 1:
            raise TestFailure(
                "ListingsTest - FAIL: One listing should be returned")
        if resp[0]["acceptedCurrencies"] != [currency]:
            raise TestFailure(
                "ListingsTest - FAIL: Listing should have acceptedCurrences")

        # check listing show page from another node
        api_url = vendor["gateway_url"] + "ob/listing/" + vendor[
            "peerId"] + "/" + slug
        r = requests.get(api_url)
        if r.status_code == 404:
            raise TestFailure(
                "ListingsTest - FAIL: Listings get endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "ListingsTest - FAIL: Listings GET failed. Reason: %s",
                resp["reason"])

        resp = json.loads(r.text)
        if resp["listing"]["metadata"]["acceptedCurrencies"] != [
                currency.upper()
        ]:
            raise TestFailure(
                "ListingsTest - FAIL: Listing should have acceptedCurrences in metadata"
            )

        print("ListingsTest - PASS")
    def run_test(self):
        merchant = self.nodes[0]
        customer = self.nodes[1]
        moderator = self.nodes[2]

        escrow_timeout_hours = 1

        # generate some coins and send them to customer
        time.sleep(4)
        api_url = customer["gateway_url"] + "wallet/address"
        r = requests.get(api_url)
        if r.status_code == 200:
            resp = json.loads(r.text)
            address = resp["address"]
        elif r.status_code == 404:
            raise TestFailure("RejectDisputedEscrowRelease - FAIL: Address endpoint not found")
        else:
            raise TestFailure("RejectDisputedEscrowRelease - FAIL: Unknown response")
        self.send_bitcoin_cmd("sendtoaddress", address, 10)
        time.sleep(20)

        # create a profile for moderator
        pro = {"name": "Moderator"}
        api_url = moderator["gateway_url"] + "ob/profile"
        r = requests.post(api_url, data=json.dumps(pro, indent=4))
        if r.status_code == 404:
            raise TestFailure("RejectDisputedEscrowRelease - FAIL: Profile post endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure("RejectDisputedEscrowRelease - FAIL: Profile POST failed. Reason: %s", resp["reason"])
        time.sleep(4)

        # make moderator a moderator
        with open('testdata/moderation.json') as listing_file:
            moderation_json = json.load(listing_file, object_pairs_hook=OrderedDict)
        api_url = moderator["gateway_url"] + "ob/moderator"
        r = requests.put(api_url, data=json.dumps(moderation_json, indent=4))
        if r.status_code == 404:
            raise TestFailure("RejectDisputedEscrowRelease - FAIL: Moderator post endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure("RejectDisputedEscrowRelease - FAIL: Moderator POST failed. Reason: %s", resp["reason"])
        moderatorId = moderator["peerId"]
        time.sleep(4)

        # post profile for merchant
        with open('testdata/profile.json') as profile_file:
            profile_json = json.load(profile_file, object_pairs_hook=OrderedDict)
        api_url = merchant["gateway_url"] + "ob/profile"
        requests.post(api_url, data=json.dumps(profile_json, indent=4))

        # post listing to merchant
        with open('testdata/listing.json') as listing_file:
            listing_json = json.load(listing_file, object_pairs_hook=OrderedDict)
        if self.bitcoincash:
            listing_json["metadata"]["pricingCurrency"] = "tbch"
        slug = listing_json["slug"]
        listing_json["moderators"] = [moderatorId]
        listing_json["metadata"]["escrowTimeoutHours"] = escrow_timeout_hours
        api_url = merchant["gateway_url"] + "ob/listing"
        r = requests.post(api_url, data=json.dumps(listing_json, indent=4))
        if r.status_code == 404:
            raise TestFailure("RejectDisputedEscrowRelease - FAIL: Listing post endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure("RejectDisputedEscrowRelease - FAIL: Listing POST failed. Reason: %s", resp["reason"])
        resp = json.loads(r.text)
        slug = resp["slug"]
        time.sleep(4)

        # get listing hash
        api_url = merchant["gateway_url"] + "ipns/" + merchant["peerId"] + "/listings.json"
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure("RejectDisputedEscrowRelease - FAIL: Couldn't get listing index")
        resp = json.loads(r.text)
        listingId = resp[0]["hash"]

        # customer send order
        with open('testdata/order_direct.json') as order_file:
            order_json = json.load(order_file, object_pairs_hook=OrderedDict)
        order_json["items"][0]["listingHash"] = listingId
        order_json["moderator"] = moderatorId
        api_url = customer["gateway_url"] + "ob/purchase"
        r = requests.post(api_url, data=json.dumps(order_json, indent=4))
        if r.status_code == 404:
            raise TestFailure("RejectDisputedEscrowRelease - FAIL: Purchase post endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            self.print_logs(merchant, "ob.log")
            raise TestFailure("RejectDisputedEscrowRelease - FAIL: Purchase POST failed. Reason: %s", resp["reason"])
        resp = json.loads(r.text)
        orderId = resp["orderId"]
        payment_address = resp["paymentAddress"]
        payment_amount = resp["amount"]

        # check the purchase saved correctly
        api_url = customer["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure("RejectDisputedEscrowRelease - FAIL: Couldn't load order from Customer")
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_PAYMENT":
            raise TestFailure("RejectDisputedEscrowRelease - FAIL: Customer purchase saved in incorrect state")
        if resp["funded"] == True:
            raise TestFailure("RejectDisputedEscrowRelease - FAIL: Customer incorrectly saved as funded")

        # check the sale saved correctly
        api_url = merchant["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure("RejectDisputedEscrowRelease - FAIL: Couldn't load order from Merchant")
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_PAYMENT":
            raise TestFailure("RejectDisputedEscrowRelease - FAIL: Merchant purchase saved in incorrect state")
        if resp["funded"] == True:
            raise TestFailure("RejectDisputedEscrowRelease - FAIL: Merchant incorrectly saved as funded")

        # fund order
        spend = {
            "address": payment_address,
            "amount": payment_amount,
            "feeLevel": "NORMAL"
        }
        api_url = customer["gateway_url"] + "wallet/spend"
        r = requests.post(api_url, data=json.dumps(spend, indent=4))
        if r.status_code == 404:
            raise TestFailure("RejectDisputedEscrowRelease - FAIL: Spend post endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure("RejectDisputedEscrowRelease - FAIL: Spend POST failed. Reason: %s", resp["reason"])
        time.sleep(20)

        # check customer detected payment
        api_url = customer["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure("RejectDisputedEscrowRelease - FAIL: Couldn't load order from Customer")
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_FULFILLMENT":
            raise TestFailure("RejectDisputedEscrowRelease - FAIL: Customer failed to detect his payment")
        if resp["funded"] == False:
            raise TestFailure("RejectDisputedEscrowRelease - FAIL: Customer incorrectly saved as unfunded")

        # check merchant detected payment
        api_url = merchant["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure("RejectDisputedEscrowRelease - FAIL: Couldn't load order from Merchant")
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_FULFILLMENT":
            raise TestFailure("RejectDisputedEscrowRelease - FAIL: Merchant failed to detect payment")
        if resp["funded"] == False:
            raise TestFailure("RejectDisputedEscrowRelease - FAIL: Merchant incorrectly saved as unfunded")

        # merchant send order fulfillment
        with open('testdata/fulfillment.json') as fulfillment_file:
            fulfillment_json = json.load(fulfillment_file, object_pairs_hook=OrderedDict)
        fulfillment_json["slug"] = slug
        fulfillment_json["orderId"] = orderId
        api_url = merchant["gateway_url"] + "ob/orderfulfillment"
        r = requests.post(api_url, data=json.dumps(fulfillment_json, indent=4))
        if r.status_code == 404:
            raise TestFailure("RejectDisputedEscrowRelease - FAIL: Fulfillment post endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure("RejectDisputedEscrowRelease - FAIL: Fulfillment POST failed. Reason: %s", resp["reason"])
        time.sleep(4)

        # check customer received fulfillment
        api_url = customer["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure("RejectDisputedEscrowRelease - FAIL: Couldn't load order from Customer")
        resp = json.loads(r.text)
        if resp["state"] != "FULFILLED":
            raise TestFailure("RejectDisputedEscrowRelease - FAIL: Customer failed to detect order fulfillment")

        # check merchant set fulfillment correctly
        api_url = merchant["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure("RejectDisputedEscrowRelease - FAIL: Couldn't load order from Customer")
        resp = json.loads(r.text)
        if resp["state"] != "FULFILLED":
            raise TestFailure("RejectDisputedEscrowRelease - FAIL: Merchant failed to order fulfillment")

        # Customer open dispute
        dispute = {
            "orderId": orderId,
            "claim": "Bastard ripped me off"
        }
        api_url = customer["gateway_url"] + "ob/opendispute/"
        r = requests.post(api_url, data=json.dumps(dispute, indent=4))
        if r.status_code == 404:
            raise TestFailure("RejectDisputedEscrowRelease - FAIL: OpenDispute post endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure("RejectDisputedEscrowRelease - FAIL: OpenDispute POST failed. Reason: %s", resp["reason"])
        time.sleep(4)

        # Customer check dispute opened correctly
        api_url = customer["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure("RejectDisputedEscrowRelease - FAIL: Couldn't load order from Customer")
        resp = json.loads(r.text)
        if resp["state"] != "DISPUTED":
            raise TestFailure("RejectDisputedEscrowRelease - FAIL: Customer failed to detect his dispute")

        # Merchant check dispute opened correctly
        api_url = merchant["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure("RejectDisputedEscrowRelease - FAIL: Couldn't load case from Marchant")
        resp = json.loads(r.text, object_pairs_hook=OrderedDict)
        if resp["state"] != "DISPUTED":
            raise TestFailure("RejectDisputedEscrowRelease - FAIL: Merchant failed to detect the dispute")

        # Moderator check dispute opened correctly
        api_url = moderator["gateway_url"] + "ob/case/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure("RejectDisputedEscrowRelease - FAIL: Couldn't load case from Moderator")
        resp = json.loads(r.text, object_pairs_hook=OrderedDict)
        if resp["state"] != "DISPUTED":
            raise TestFailure("RejectDisputedEscrowRelease - FAIL: Moderator failed to detect the dispute")

        # Merchant attempt to release funds before dispute timeout hits
        release = {
            "OrderID": orderId,
        }
        api_url = merchant["gateway_url"] + "ob/releaseescrow/"
        r = requests.post(api_url, data=json.dumps(release, indent=4))
        if r.status_code == 500:
            resp = json.loads(r.text)
            raise TestFailure("RejectDisputedEscrowRelease - FAIL: Release escrow internal server error %s", resp["reason"])
        elif r.status_code != 401:
            resp = json.loads(r.text)
            raise TestFailure("RejectDisputedEscrowRelease - FAIL: Failed to raise error when releasing escrow after escrow timeout but before dispute timeout")

        # A hack allows dispute timeout to only be 10 seconds while running the server on testnet.
        time.sleep(20)

        for i in range(6):
            self.send_bitcoin_cmd("generate", 1)
            time.sleep(3)

        # Merchant attempt to release funds after timeout
        release = {
            "OrderID": orderId,
        }
        api_url = merchant["gateway_url"] + "ob/releaseescrow/"
        r = requests.post(api_url, data=json.dumps(release, indent=4))
        if r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure("RejectDisputedEscrowRelease - FAIL: Release escrow error %s", resp["reason"])

        time.sleep(20)

        self.send_bitcoin_cmd("generate", 1)
        time.sleep(2)

        # Check the funds moved into merchant's wallet
        api_url = merchant["gateway_url"] + "wallet/balance"
        r = requests.get(api_url)
        if r.status_code == 200:
            resp = json.loads(r.text)
            confirmed = int(resp["confirmed"])
            #unconfirmed = int(resp["unconfirmed"])
            if confirmed <= 0:
                raise TestFailure("RefundDirectTest - FAIL: Merchant failed to receive the multisig payout")
        else:
            raise TestFailure("RefundDirectTest - FAIL: Failed to query Merchant's balance")

        print("RejectDisputedEscrowRelease - PASS")
    def run_test(self):
        vendor = self.nodes[1]

        # post profile for vendor
        with open('testdata/profile.json') as profile_file:
            profile_json = json.load(profile_file,
                                     object_pairs_hook=OrderedDict)
        api_url = vendor["gateway_url"] + "ob/profile"
        requests.post(api_url, data=json.dumps(profile_json, indent=4))

        # check index
        r = requests.get(vendor["gateway_url"] + "ob/listings")
        resp = json.loads(r.text)
        if len(resp) != 0:
            raise TestFailure(
                "ManageCryptoListingsTest - FAIL: Incorrect listing count: %d",
                len(resp))

        # post listing to vendor
        with open('testdata/listing_crypto.json') as listing_file:
            listing_json = json.load(listing_file,
                                     object_pairs_hook=OrderedDict)

        listing_json["coinType"] = "TETH"
        api_url = vendor["gateway_url"] + "ob/listing"
        r = requests.post(api_url, data=json.dumps(listing_json, indent=4))
        if r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "ManageCryptoListingsTest - FAIL: Listing POST failed. Reason: %s",
                resp["reason"])
        slug = json.loads(r.text)["slug"]

        # check index
        r = requests.get(vendor["gateway_url"] + "ob/listings")
        resp = json.loads(r.text)
        if len(resp) != 1:
            raise TestFailure(
                "ManageCryptoListingsTest - FAIL: Incorrect listing count: %d",
                len(resp))
        for listing in resp:
            if listing['contractType'] == 'CRYPTOCURRENCY':
                if listing["coinType"] != "TETH":
                    raise TestFailure(
                        "ManageCryptoListingsTest - FAIL: cryptoCurrencyCode incorrect: %s",
                        listing["cryptoCurrencyCode"])

        # delete listing
        api_url = vendor["gateway_url"] + "ob/listing/" + slug
        r = requests.delete(api_url)
        if r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "ManageCryptoListingsTest - FAIL: Listing DELETE failed. Reason: %s",
                resp["reason"])

        # check index
        r = requests.get(vendor["gateway_url"] + "ob/listings")
        resp = json.loads(r.text)
        if len(resp) != 0:
            raise TestFailure(
                "ManageCryptoListingsTest - FAIL: Incorrect listing count: %d",
                len(resp))

        print("ManageCryptoListingsTest - PASS")
Beispiel #16
0
    def run_test(self):
        alice = self.nodes[0]
        bob = self.nodes[1]

        # post profile for alice
        with open('testdata/profile.json') as profile_file:
            profile_json = json.load(profile_file,
                                     object_pairs_hook=OrderedDict)
        api_url = alice["gateway_url"] + "ob/profile"
        requests.post(api_url, data=json.dumps(profile_json, indent=4))

        # post listing to alice
        with open('testdata/listing.json') as listing_file:
            listing_json = json.load(listing_file,
                                     object_pairs_hook=OrderedDict)

        api_url = alice["gateway_url"] + "ob/listing"
        r = requests.post(api_url, data=json.dumps(listing_json, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "PurchaseDirectOfflineTest - FAIL: Listing post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "PurchaseDirectOfflineTest - FAIL: Listing POST failed. Reason: %s",
                resp["reason"])
        time.sleep(20)

        # get listing hash
        api_url = alice["gateway_url"] + "ipns/" + alice[
            "peerId"] + "/listings.json"
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "PurchaseDirectOfflineTest - FAIL: Couldn't get listing index")
        resp = json.loads(r.text)
        listingId = resp[0]["hash"]

        # bob fetch listing to cache
        api_url = bob["gateway_url"] + "ipfs/" + listingId
        requests.get(api_url)

        # generate some coins and send them to bob
        api_url = bob["gateway_url"] + "wallet/address"
        r = requests.get(api_url)
        if r.status_code == 200:
            resp = json.loads(r.text)
            address = resp["address"]
        elif r.status_code == 404:
            raise TestFailure(
                "PurchaseDirectOfflineTest - FAIL: Address endpoint not found")
        else:
            raise TestFailure(
                "PurchaseDirectOfflineTest - FAIL: Unknown response")
        self.send_bitcoin_cmd("sendtoaddress", address, 10)
        time.sleep(3)

        # shutdown alice
        api_url = alice["gateway_url"] + "ob/shutdown"
        requests.post(api_url, data="")
        time.sleep(4)

        # bob send order
        with open('testdata/order_direct.json') as order_file:
            order_json = json.load(order_file, object_pairs_hook=OrderedDict)
        order_json["items"][0]["listingHash"] = listingId
        api_url = bob["gateway_url"] + "ob/purchase"
        r = requests.post(api_url, data=json.dumps(order_json, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "PurchaseDirectOfflineTest - FAIL: Purchase post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "PurchaseDirectOfflineTest - FAIL: Purchase POST failed. Reason: %s",
                resp["reason"])
        resp = json.loads(r.text)
        orderId = resp["orderId"]
        payment_address = resp["paymentAddress"]
        payment_amount = resp["amount"]
        if resp["vendorOnline"] == True:
            raise TestFailure(
                "PurchaseDirectOfflineTest - FAIL: Purchase returned vendor is online"
            )

        # check the purchase saved correctly
        api_url = bob["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "PurchaseDirectOfflineTest - FAIL: Couldn't load order from Bob"
            )
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_PAYMENT":
            raise TestFailure(
                "PurchaseDirectOfflineTest - FAIL: Bob purchase saved in incorrect state"
            )
        if resp["funded"] == True:
            raise TestFailure(
                "PurchaseDirectOfflineTest - FAIL: Bob incorrectly saved as funded"
            )

        # fund order
        spend = {
            "address": payment_address,
            "amount": payment_amount,
            "feeLevel": "NORMAL"
        }
        api_url = bob["gateway_url"] + "wallet/spend"
        r = requests.post(api_url, data=json.dumps(spend, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "PurchaseDirectOfflineTest - FAIL: Spend post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "PurchaseDirectOfflineTest - FAIL: Purchase POST failed. Reason: %s",
                resp["reason"])
        time.sleep(20)

        # check bob detected payment
        api_url = bob["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "PurchaseDirectOfflineTest - FAIL: Couldn't load order from Bob"
            )
        resp = json.loads(r.text)
        if len(resp["paymentAddressTransactions"]) <= 0:
            raise TestFailure(
                "PurchaseDirectOfflineTest - FAIL: Bob failed to detect his payment"
            )
        if resp["funded"] == False:
            raise TestFailure(
                "PurchaseDirectOfflineTest - FAIL: Bob incorrectly saved as unfunded"
            )
        if resp["state"] != "PENDING":
            raise TestFailure(
                "PurchaseDirectOfflineTest - FAIL: Bob purchase saved in incorrect state"
            )

        # generate one more block containing this tx
        self.send_bitcoin_cmd("generate", 1)

        # startup alice again
        self.start_node(alice)
        time.sleep(45)

        # check alice detected order and payment
        api_url = alice["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "PurchaseDirectOfflineTest - FAIL: Couldn't load order from Alice"
            )
        resp = json.loads(r.text)
        if resp["state"] != "PENDING":
            raise TestFailure(
                "PurchaseDirectOfflineTest - FAIL: Alice failed to detect payment"
            )
        if resp["funded"] == False:
            raise TestFailure(
                "PurchaseDirectOfflineTest - FAIL: Alice incorrectly saved as unfunded"
            )

        # check alice balance is zero
        api_url = alice["gateway_url"] + "wallet/balance"
        r = requests.get(api_url)
        if r.status_code == 200:
            resp = json.loads(r.text)
            confirmed = int(resp["confirmed"])
            unconfirmed = int(resp["unconfirmed"])
            if confirmed + unconfirmed > 0:
                raise TestFailure(
                    "PurchaseDirectOfflineTest - FAIL: Alice should have zero balance at this point"
                )
        else:
            raise TestFailure(
                "PurchaseDirectOfflineTest - FAIL: Failed to query Alice's balance"
            )
        time.sleep(1)

        # alice confirm offline order
        api_url = alice["gateway_url"] + "ob/orderconfirmation"
        oc = {"orderId": orderId, "reject": False}
        r = requests.post(api_url, data=json.dumps(oc, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "PurchaseDirectOfflineTest - FAIL: Order confirmation post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "PurchaseDirectOfflineTest - FAIL: Purchase POST failed. Reason: %s",
                resp["reason"])
        time.sleep(10)

        self.send_bitcoin_cmd("generate", 1)
        time.sleep(2)

        # Check the funds moved into alice's wallet
        api_url = alice["gateway_url"] + "wallet/balance"
        r = requests.get(api_url)
        if r.status_code == 200:
            resp = json.loads(r.text)
            confirmed = int(resp["confirmed"])
            #unconfirmed = int(resp["unconfirmed"])
            if confirmed <= 0:
                raise TestFailure(
                    "PurchaseDirectOfflineTest - FAIL: Alice failed to receive the multisig payout"
                )
        else:
            raise TestFailure(
                "PurchaseDirectOfflineTest - FAIL: Failed to query Alice's balance"
            )

        # check bob detected order confirmation and outgoing transaction
        api_url = bob["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "PurchaseDirectOnlineTest - FAIL: Couldn't load order from Bob"
            )
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_FULFILLMENT":
            raise TestFailure(
                "PurchaseDirectOnlineTest - FAIL: Bob failed to set state correctly"
            )
        if resp["funded"] == False:
            raise TestFailure(
                "PurchaseDirectOnlineTest - FAIL: Bob incorrectly saved as unfunded"
            )

        # check alice set state correctly
        api_url = alice["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "PurchaseDirectOnlineTest - FAIL: Couldn't load order from Alice"
            )
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_FULFILLMENT":
            raise TestFailure(
                "PurchaseDirectOnlineTest - FAIL: Alice failed to detect payment"
            )
        if resp["funded"] == False:
            raise TestFailure(
                "PurchaseDirectOnlineTest - FAIL: Alice incorrectly saved as unfunded"
            )

        print("PurchaseDirectOfflineTest - PASS")
Beispiel #17
0
    def run_test(self):
        alice = self.nodes[0]
        bob = self.nodes[1]
        charlie = self.nodes[2]

        # generate some coins and send them to bob
        time.sleep(4)
        api_url = bob["gateway_url"] + "wallet/address"
        r = requests.get(api_url)
        if r.status_code == 200:
            resp = json.loads(r.text)
            address = resp["address"]
        elif r.status_code == 404:
            raise TestFailure("EscrowTimeoutRelease - FAIL: Address endpoint not found")
        else:
            raise TestFailure("EscrowTimeoutRelease - FAIL: Unknown response")
        self.send_bitcoin_cmd("sendtoaddress", address, 10)
        time.sleep(20)

        # create a profile for charlie
        pro = {"name": "Charlie"}
        api_url = charlie["gateway_url"] + "ob/profile"
        r = requests.post(api_url, data=json.dumps(pro, indent=4))
        if r.status_code == 404:
            raise TestFailure("EscrowTimeoutRelease - FAIL: Profile post endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure("EscrowTimeoutRelease - FAIL: Profile POST failed. Reason: %s", resp["reason"])
        time.sleep(4)

        # make charlie a moderator
        with open('testdata/moderation.json') as listing_file:
            moderation_json = json.load(listing_file, object_pairs_hook=OrderedDict)
        api_url = charlie["gateway_url"] + "ob/moderator"
        r = requests.put(api_url, data=json.dumps(moderation_json, indent=4))
        if r.status_code == 404:
            raise TestFailure("EscrowTimeoutRelease - FAIL: Moderator post endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure("EscrowTimeoutRelease - FAIL: Moderator POST failed. Reason: %s", resp["reason"])
        moderatorId = charlie["peerId"]
        time.sleep(4)

        # post profile for alice
        with open('testdata/profile.json') as profile_file:
            profile_json = json.load(profile_file, object_pairs_hook=OrderedDict)
        api_url = alice["gateway_url"] + "ob/profile"
        requests.post(api_url, data=json.dumps(profile_json, indent=4))

        # post listing to alice
        with open('testdata/listing.json') as listing_file:
            listing_json = json.load(listing_file, object_pairs_hook=OrderedDict)
        if self.bitcoincash:
            listing_json["metadata"]["pricingCurrency"] = "tbch"
        slug = listing_json["slug"]
        listing_json["moderators"] = [moderatorId]
        listing_json["metadata"]["escrowTimeoutHours"] = 1
        api_url = alice["gateway_url"] + "ob/listing"
        r = requests.post(api_url, data=json.dumps(listing_json, indent=4))
        if r.status_code == 404:
            raise TestFailure("EscrowTimeoutRelease - FAIL: Listing post endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure("EscrowTimeoutRelease - FAIL: Listing POST failed. Reason: %s", resp["reason"])
        resp = json.loads(r.text)
        slug = resp["slug"]
        time.sleep(4)

        # get listing hash
        api_url = alice["gateway_url"] + "ob/listings/" + alice["peerId"]
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure("EscrowTimeoutRelease - FAIL: Couldn't get listing index")
        resp = json.loads(r.text)
        listingId = resp[0]["hash"]

        # bob send order
        with open('testdata/order_direct.json') as order_file:
            order_json = json.load(order_file, object_pairs_hook=OrderedDict)
        order_json["items"][0]["listingHash"] = listingId
        order_json["moderator"] = moderatorId
        api_url = bob["gateway_url"] + "ob/purchase"
        r = requests.post(api_url, data=json.dumps(order_json, indent=4))
        if r.status_code == 404:
            raise TestFailure("EscrowTimeoutRelease - FAIL: Purchase post endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            self.print_logs(alice, "ob.log")
            raise TestFailure("EscrowTimeoutRelease - FAIL: Purchase POST failed. Reason: %s", resp["reason"])
        resp = json.loads(r.text)
        orderId = resp["orderId"]
        payment_address = resp["paymentAddress"]
        payment_amount = resp["amount"]

        # check the purchase saved correctly
        api_url = bob["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure("EscrowTimeoutRelease - FAIL: Couldn't load order from Bob")
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_PAYMENT":
            raise TestFailure("EscrowTimeoutRelease - FAIL: Bob purchase saved in incorrect state")
        if resp["funded"] == True:
            raise TestFailure("EscrowTimeoutRelease - FAIL: Bob incorrectly saved as funded")

        # check the sale saved correctly
        api_url = alice["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure("EscrowTimeoutRelease - FAIL: Couldn't load order from Alice")
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_PAYMENT":
            raise TestFailure("EscrowTimeoutRelease - FAIL: Alice purchase saved in incorrect state")
        if resp["funded"] == True:
            raise TestFailure("EscrowTimeoutRelease - FAIL: Alice incorrectly saved as funded")

        # fund order
        spend = {
            "address": payment_address,
            "amount": payment_amount,
            "feeLevel": "NORMAL"
        }
        api_url = bob["gateway_url"] + "wallet/spend"
        r = requests.post(api_url, data=json.dumps(spend, indent=4))
        if r.status_code == 404:
            raise TestFailure("EscrowTimeoutRelease - FAIL: Spend post endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure("EscrowTimeoutRelease - FAIL: Spend POST failed. Reason: %s", resp["reason"])
        time.sleep(20)

        # check bob detected payment
        api_url = bob["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure("EscrowTimeoutRelease - FAIL: Couldn't load order from Bob")
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_FULFILLMENT":
            raise TestFailure("EscrowTimeoutRelease - FAIL: Bob failed to detect his payment")
        if resp["funded"] == False:
            raise TestFailure("EscrowTimeoutRelease - FAIL: Bob incorrectly saved as unfunded")

        # check alice detected payment
        api_url = alice["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure("EscrowTimeoutRelease - FAIL: Couldn't load order from Alice")
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_FULFILLMENT":
            raise TestFailure("EscrowTimeoutRelease - FAIL: Alice failed to detect payment")
        if resp["funded"] == False:
            raise TestFailure("EscrowTimeoutRelease - FAIL: Alice incorrectly saved as unfunded")

        # alice send order fulfillment
        with open('testdata/fulfillment.json') as fulfillment_file:
            fulfillment_json = json.load(fulfillment_file, object_pairs_hook=OrderedDict)
        fulfillment_json["slug"] = slug
        fulfillment_json["orderId"] = orderId
        api_url = alice["gateway_url"] + "ob/orderfulfillment"
        r = requests.post(api_url, data=json.dumps(fulfillment_json, indent=4))
        if r.status_code == 404:
            raise TestFailure("EscrowTimeoutRelease - FAIL: Fulfillment post endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure("EscrowTimeoutRelease - FAIL: Fulfillment POST failed. Reason: %s", resp["reason"])
        time.sleep(4)

        # check bob received fulfillment
        api_url = bob["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure("EscrowTimeoutRelease - FAIL: Couldn't load order from Bob")
        resp = json.loads(r.text)
        if resp["state"] != "FULFILLED":
            raise TestFailure("EscrowTimeoutRelease - FAIL: Bob failed to detect order fulfillment")

        # check alice set fulfillment correctly
        api_url = alice["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure("EscrowTimeoutRelease - FAIL: Couldn't load order from Bob")
        resp = json.loads(r.text)
        if resp["state"] != "FULFILLED":
            raise TestFailure("EscrowTimeoutRelease - FAIL: Alice failed to order fulfillment")

        # Alice attempt to release funds before timeout hit
        release = {
            "OrderID": orderId,
        }
        api_url = alice["gateway_url"] + "ob/releaseescrow/"
        r = requests.post(api_url, data=json.dumps(release, indent=4))
        if r.status_code == 500:
            resp = json.loads(r.text)
            raise TestFailure("EscrowTimeoutRelease - FAIL: Release escrow internal server error %s", resp["reason"])
        elif r.status_code != 401:
            raise TestFailure("EscrowTimeoutRelease - FAIL: Failed to raise error when releasing escrow before timeout")

        for i in range(6):
            self.send_bitcoin_cmd("generate", 1)
            time.sleep(3)

        # Alice attempt to release funds again
        release = {
            "OrderID": orderId,
        }
        api_url = alice["gateway_url"] + "ob/releaseescrow/"
        r = requests.post(api_url, data=json.dumps(release, indent=4))
        if r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure("EscrowTimeoutRelease - FAIL: Release escrow error %s", resp["reason"])

        time.sleep(20)

        self.send_bitcoin_cmd("generate", 1)
        time.sleep(2)

        # Check the funds moved into alice's wallet
        api_url = alice["gateway_url"] + "wallet/balance"
        r = requests.get(api_url)
        if r.status_code == 200:
            resp = json.loads(r.text)
            confirmed = int(resp["confirmed"])
            #unconfirmed = int(resp["unconfirmed"])
            if confirmed <= 0:
                raise TestFailure("RefundDirectTest - FAIL: Alice failed to receive the multisig payout")
        else:
            raise TestFailure("RefundDirectTest - FAIL: Failed to query Alice's balance")

        # check alice's order was set to payment finalized
        api_url = alice["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure("EscrowTimeoutRelease - FAIL: Couldn't load order from Bob")
        resp = json.loads(r.text)
        if resp["state"] != "PAYMENT_FINALIZED":
            raise TestFailure("EscrowTimeoutRelease - FAIL: Alice failed to set order to payment finalized")

        # check bob's order was set to payment finalized
        api_url = bob["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure("EscrowTimeoutRelease - FAIL: Couldn't load order from Bob")
        resp = json.loads(r.text)
        if resp["state"] != "PAYMENT_FINALIZED":
            raise TestFailure("EscrowTimeoutRelease - FAIL: Bob failed to set order to payment finalized")

        print("EscrowTimeoutRelease - PASS")
Beispiel #18
0
    def run_test(self):
        alice = self.nodes[0]
        bob = self.nodes[1]

        with open('testdata/listing.json') as listing_file:
            listing_json = json.load(listing_file,
                                     object_pairs_hook=OrderedDict)

        # Create profile
        with open('testdata/profile.json') as profile_file:
            profile_json = json.load(profile_file,
                                     object_pairs_hook=OrderedDict)
        api_url = alice["gateway_url"] + "ob/profile"
        r = requests.post(api_url, data=json.dumps(profile_json, indent=4))
        resp = json.loads(r.text)
        if r.status_code != 200:
            raise TestFailure(
                "InventoryTest - FAIL: Profile POST failed. Reason: %s",
                resp["reason"])

        # Create 3 listings as alice
        for x in range(0, 3):
            api_url = alice["gateway_url"] + "ob/listing"
            r = requests.post(api_url, data=json.dumps(listing_json, indent=4))
            resp = json.loads(r.text)
            if r.status_code != 200:
                raise TestFailure(
                    "InventoryTest - FAIL: Listing POST failed. Reason: %s",
                    resp["reason"])

        # Create 1 listing as bob
        api_url = bob["gateway_url"] + "ob/listing"
        r = requests.post(api_url, data=json.dumps(listing_json, indent=4))
        resp = json.loads(r.text)
        if r.status_code != 200:
            raise TestFailure(
                "InventoryTest - FAIL: Listing POST failed. Reason: %s",
                resp["reason"])

        # Get profile
        api_url = alice["gateway_url"] + "ob/profile"
        r = requests.get(api_url)
        resp = json.loads(r.text)
        if r.status_code != 200:
            raise TestFailure(
                "InventoryTest - FAIL: Profile GET failed. Reason: %s",
                resp["reason"])
        alicePeerID = resp["peerID"]

        # Get own inventory
        api_url = bob["gateway_url"] + "ob/inventory"
        r = requests.get(api_url)
        resp = json.loads(r.text)
        if r.status_code != 200:
            raise TestFailure(
                "InventoryTest - FAIL: Inventory GET failed. Reason: %s",
                resp["reason"])
        if resp["ron-swanson-tshirt"]["inventory"] != 213:
            raise TestFailure(
                "InventoryTest - FAIL: Inventory GET should return the correct quantity)"
            )
        if not self.assert_correct_time(
                resp["ron-swanson-tshirt"]["lastUpdated"]):
            raise TestFailure(
                "InventoryTest - FAIL: Inventory GET did not return a correct looking timestamp"
            )

        # Get alice's inventory as bob
        api_url = bob["gateway_url"] + "ob/inventory/" + alicePeerID
        r = requests.get(api_url)
        resp = json.loads(r.text)
        if r.status_code != 200:
            raise TestFailure(
                "InventoryTest - FAIL: Inventory GET failed. Reason: %s",
                resp["reason"])
        if len(resp) != 3:
            raise TestFailure(
                "InventoryTest - FAIL: Inventory GET did not return the correct number of items"
            )
        if resp["ron-swanson-tshirt"]["inventory"] != 213:
            raise TestFailure(
                "InventoryTest - FAIL: Inventory GET did not return correct count"
            )
        if not self.assert_correct_time(
                resp["ron-swanson-tshirt"]["lastUpdated"]):
            raise TestFailure(
                "InventoryTest - FAIL: Inventory GET did not return a correct looking timestamp"
            )

        # Get alice's inventory for specific slug as bob
        api_url = bob[
            "gateway_url"] + "ob/inventory/" + alicePeerID + "/ron-swanson-tshirt"
        r = requests.get(api_url)
        resp = json.loads(r.text)
        if r.status_code != 200:
            raise TestFailure(
                "InventoryTest - FAIL: Inventory GET failed. Reason: %s",
                resp["reason"])
        if resp["inventory"] != 213:
            raise TestFailure(
                "InventoryTest - FAIL: Inventory GET did not return correct count"
            )
        if not self.assert_correct_time(resp["lastUpdated"]):
            raise TestFailure(
                "InventoryTest - FAIL: Inventory GET did not return a correct looking timestamp"
            )

        # Get a non existant slug from alice's inventory as bob
        api_url = bob[
            "gateway_url"] + "ob/inventory/" + alicePeerID + "/ron-swanson-loves-the-government-tshirt"
        r = requests.get(api_url)
        resp = json.loads(r.text)
        if r.status_code != 500:
            raise TestFailure(
                "InventoryTest - FAIL: Inventory GET non-existant slug did not return an error"
            )
        if resp["success"]:
            raise TestFailure(
                "InventoryTest - FAIL: Inventory GET non-existant slug did not return an error"
            )
        if resp["reason"] != "Could not find slug in inventory":
            raise TestFailure(
                "InventoryTest - FAIL: Inventory GET non-existant slug failed with the wrong error"
            )

        # Try to get a non existant peer's inventory
        api_url = bob[
            "gateway_url"] + "ob/inventory/Qmf56jASQYk7ccmyUHQssemyQc3YmEqiSos6GubHM3UtNS"
        r = requests.get(api_url)
        resp = json.loads(r.text)
        if r.status_code != 500:
            raise TestFailure(
                "InventoryTest - FAIL: Inventory GET non-existant peer did not return an error"
            )
        if resp["success"]:
            raise TestFailure(
                "InventoryTest - FAIL: Inventory GET non-existant peer did not return an error"
            )
        if resp["reason"] != "Could not resolve name.":
            raise TestFailure(
                "InventoryTest - FAIL: Inventory GET non-existant peer failed with the wrong error"
            )
Beispiel #19
0
    def run_test(self):
        alice = self.nodes[0]
        bob = self.nodes[1]
        charlie = self.nodes[2]

        # generate some coins and send them to bob
        time.sleep(4)
        api_url = bob["gateway_url"] + "wallet/address"
        r = requests.get(api_url)
        if r.status_code == 200:
            resp = json.loads(r.text)
            address = resp["address"]
        elif r.status_code == 404:
            raise TestFailure(
                "RefundModeratedTest - FAIL: Address endpoint not found")
        else:
            raise TestFailure("RefundModeratedTest - FAIL: Unknown response")
        self.send_bitcoin_cmd("sendtoaddress", address, 10)
        time.sleep(20)

        # create a profile for charlie
        pro = {"name": "Charlie"}
        api_url = charlie["gateway_url"] + "ob/profile"
        r = requests.post(api_url, data=json.dumps(pro, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "RefundModeratedTest - FAIL: Profile post endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "RefundModeratedTest - FAIL: Profile POST failed. Reason: %s",
                resp["reason"])
        time.sleep(4)

        # make charlie a moderator
        with open('testdata/moderation.json') as listing_file:
            moderation_json = json.load(listing_file,
                                        object_pairs_hook=OrderedDict)
        api_url = charlie["gateway_url"] + "ob/moderator"
        r = requests.put(api_url, data=json.dumps(moderation_json, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "RefundModeratedTest - FAIL: Moderator post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "RefundModeratedTest - FAIL: Moderator POST failed. Reason: %s",
                resp["reason"])
        moderatorId = charlie["peerId"]
        time.sleep(4)

        # post profile for alice
        with open('testdata/profile.json') as profile_file:
            profile_json = json.load(profile_file,
                                     object_pairs_hook=OrderedDict)
        api_url = alice["gateway_url"] + "ob/profile"
        requests.post(api_url, data=json.dumps(profile_json, indent=4))

        # post listing to alice
        with open('testdata/listing.json') as listing_file:
            listing_json = json.load(listing_file,
                                     object_pairs_hook=OrderedDict)
        if self.bitcoincash:
            listing_json["metadata"]["pricingCurrency"] = "tbch"

        listing_json["moderators"] = [moderatorId]
        api_url = alice["gateway_url"] + "ob/listing"
        r = requests.post(api_url, data=json.dumps(listing_json, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "RefundModeratedTest - FAIL: Listing post endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "RefundModeratedTest - FAIL: Listing POST failed. Reason: %s",
                resp["reason"])
        time.sleep(4)

        # get listing hash
        api_url = alice["gateway_url"] + "ipns/" + alice[
            "peerId"] + "/listings.json"
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "RefundModeratedTest - FAIL: Couldn't get listing index")
        resp = json.loads(r.text)
        listingId = resp[0]["hash"]

        # bob send order
        with open('testdata/order_direct.json') as order_file:
            order_json = json.load(order_file, object_pairs_hook=OrderedDict)
        order_json["items"][0]["listingHash"] = listingId
        order_json["moderator"] = moderatorId
        api_url = bob["gateway_url"] + "ob/purchase"
        r = requests.post(api_url, data=json.dumps(order_json, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "RefundModeratedTest - FAIL: Purchase post endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            self.print_logs(alice, "ob.log")
            raise TestFailure(
                "RefundModeratedTest - FAIL: Purchase POST failed. Reason: %s",
                resp["reason"])
        resp = json.loads(r.text)
        orderId = resp["orderId"]
        payment_address = resp["paymentAddress"]
        payment_amount = resp["amount"]

        # check the purchase saved correctly
        api_url = bob["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "RefundModeratedTest - FAIL: Couldn't load order from Bob")
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_PAYMENT":
            raise TestFailure(
                "RefundModeratedTest - FAIL: Bob purchase saved in incorrect state"
            )
        if resp["funded"] == True:
            raise TestFailure(
                "RefundModeratedTest - FAIL: Bob incorrectly saved as funded")

        # check the sale saved correctly
        api_url = alice["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "RefundModeratedTest - FAIL: Couldn't load order from Alice")
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_PAYMENT":
            raise TestFailure(
                "RefundModeratedTest - FAIL: Alice purchase saved in incorrect state"
            )
        if resp["funded"] == True:
            raise TestFailure(
                "RefundModeratedTest - FAIL: Alice incorrectly saved as funded"
            )

        # fund order
        spend = {
            "address": payment_address,
            "amount": payment_amount,
            "feeLevel": "NORMAL"
        }
        api_url = bob["gateway_url"] + "wallet/spend"
        r = requests.post(api_url, data=json.dumps(spend, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "RefundModeratedTest - FAIL: Spend post endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "RefundModeratedTest - FAIL: Spend POST failed. Reason: %s",
                resp["reason"])
        time.sleep(20)

        # check bob detected payment
        api_url = bob["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "RefundModeratedTest - FAIL: Couldn't load order from Bob")
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_FULFILLMENT":
            raise TestFailure(
                "RefundModeratedTest - FAIL: Bob failed to detect his payment")
        if resp["funded"] == False:
            raise TestFailure(
                "RefundModeratedTest - FAIL: Bob incorrectly saved as unfunded"
            )

        # check alice detected payment
        api_url = alice["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "RefundModeratedTest - FAIL: Couldn't load order from Alice")
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_FULFILLMENT":
            raise TestFailure(
                "RefundModeratedTest - FAIL: Alice failed to detect payment")
        if resp["funded"] == False:
            raise TestFailure(
                "RefundModeratedTest - FAIL: Alice incorrectly saved as unfunded"
            )
        time.sleep(5)

        # alice refund order
        api_url = alice["gateway_url"] + "ob/refund"
        refund = {"orderId": orderId}
        r = requests.post(api_url, data=json.dumps(refund, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "RefundModeratedTest - FAIL: Refund endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "RefundModeratedTest - FAIL: Refund POST failed. Reason: %s",
                resp["reason"])
        time.sleep(20)

        # alice check order refunded correctly
        api_url = alice["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "RefundModeratedTest - FAIL: Couldn't load order from Alice")
        resp = json.loads(r.text)
        if resp["state"] != "REFUNDED":
            raise TestFailure(
                "RefundModeratedTest - FAIL: Alice failed to save as rejected")
        if len(resp["paymentAddressTransactions"]) != 2:
            raise TestFailure(
                "RefundModeratedTest - FAIL: Alice failed to detect outgoing payment"
            )
        if "refundAddressTransaction" not in resp or resp[
                "refundAddressTransaction"] == {}:
            raise TestFailure(
                "RefundModeratedTest - FAIL: Alice failed to detect refund payment"
            )

        # bob check order refunded correctly
        api_url = bob["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "RefundModeratedTest - FAIL: Couldn't load order from Bob")
        resp = json.loads(r.text)
        if resp["state"] != "REFUNDED":
            raise TestFailure(
                "RefundModeratedTest - FAIL: Bob failed to save as rejected")
        if len(resp["paymentAddressTransactions"]) != 2:
            raise TestFailure(
                "RefundModeratedTest - FAIL: Bob failed to detect outgoing payment"
            )
        if "refundAddressTransaction" not in resp or resp[
                "refundAddressTransaction"] == {}:
            raise TestFailure(
                "RefundModeratedTest - FAIL: Alice failed to detect refund payment"
            )

        self.send_bitcoin_cmd("generate", 1)
        time.sleep(2)

        # Check the funds moved into bob's wallet
        api_url = bob["gateway_url"] + "wallet/balance"
        r = requests.get(api_url)
        if r.status_code == 200:
            resp = json.loads(r.text)
            confirmed = int(resp["confirmed"])
            #unconfirmed = int(resp["unconfirmed"])
            if confirmed <= 50 - payment_amount:
                raise TestFailure(
                    "RefundModeratedTest - FAIL: Bob failed to receive the multisig payout"
                )
        else:
            raise TestFailure(
                "RefundModeratedTest - FAIL: Failed to query Bob's balance")

        print("RefundModeratedTest - PASS")
    def run_test(self):
        alice = self.nodes[1]
        bob = self.nodes[2]

        # generate some coins and send them to bob
        time.sleep(4)
        api_url = bob["gateway_url"] + "wallet/address/" + self.cointype
        r = requests.get(api_url)
        if r.status_code == 200:
            resp = json.loads(r.text)
            address = resp["address"]
        elif r.status_code == 404:
            raise TestFailure(
                "EthRejectDirectOfflineTest - FAIL: Address endpoint not found"
            )
        else:
            raise TestFailure(
                "EthRejectDirectOfflineTest - FAIL: Unknown response")
        time.sleep(20)

        # post profile for alice
        with open('testdata/v5/profile.json') as profile_file:
            profile_json = json.load(profile_file,
                                     object_pairs_hook=OrderedDict)
        api_url = alice["gateway_url"] + "ob/profile"
        requests.post(api_url, data=json.dumps(profile_json, indent=4))

        # post listing to alice
        with open('testdata/v5/eth_listing.json') as listing_file:
            listing_json = json.load(listing_file,
                                     object_pairs_hook=OrderedDict)
        listing_json["item"]["priceCurrency"]["code"] = "T" + self.cointype
        listing_json["metadata"]["acceptedCurrencies"] = ["T" + self.cointype]

        api_url = alice["gateway_url"] + "ob/listing"
        r = requests.post(api_url, data=json.dumps(listing_json, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "EthRejectDirectOfflineTest - FAIL: Listing post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "EthRejectDirectOfflineTest - FAIL: Listing POST failed. Reason: %s",
                resp["reason"])
        time.sleep(4)

        # get listing hash
        api_url = alice["gateway_url"] + "ob/listings/" + alice["peerId"]
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "EthRejectDirectOfflineTest - FAIL: Couldn't get listing index"
            )
        resp = json.loads(r.text)
        listingId = resp[0]["hash"]

        # bob fetch listing to cache
        api_url = bob["gateway_url"] + "ipfs/" + listingId
        requests.get(api_url)

        # shutdown alice
        api_url = alice["gateway_url"] + "ob/shutdown"
        requests.post(api_url, data="")
        time.sleep(4)

        # bob send order
        with open('testdata/v5/order_direct.json') as order_file:
            order_json = json.load(order_file, object_pairs_hook=OrderedDict)
        order_json["items"][0]["listingHash"] = listingId
        order_json["paymentCoin"] = "T" + self.cointype
        api_url = bob["gateway_url"] + "ob/purchase"
        r = requests.post(api_url, data=json.dumps(order_json, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "EthRejectDirectOfflineTest - FAIL: Purchase post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "EthRejectDirectOfflineTest - FAIL: Purchase POST failed. Reason: %s",
                resp["reason"])
        resp = json.loads(r.text)
        orderId = resp["orderId"]
        payment_address = resp["paymentAddress"]
        payment_amount = resp["amount"]
        if resp["vendorOnline"] == True:
            raise TestFailure(
                "EthRejectDirectOfflineTest - FAIL: Purchase returned vendor is online"
            )

        # check the purchase saved correctly
        api_url = bob["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "EthRejectDirectOfflineTest - FAIL: Couldn't load order from Bob"
            )
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_PAYMENT":
            raise TestFailure(
                "EthRejectDirectOfflineTest - FAIL: Bob purchase saved in incorrect state"
            )
        if resp["funded"] == True:
            raise TestFailure(
                "EthRejectDirectOfflineTest - FAIL: Bob incorrectly saved as funded"
            )

        # fund order
        spend = {
            "currencyCode": "T" + self.cointype,
            "address": payment_address,
            "amount": payment_amount["amount"],
            "feeLevel": "NORMAL",
            "requireAssociateOrder": True,
            "orderID": orderId
        }
        api_url = bob["gateway_url"] + "ob/orderspend"
        r = requests.post(api_url, data=json.dumps(spend, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "EthRejectDirectOfflineTest - FAIL: Spend post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "EthRejectDirectOfflineTest - FAIL: Purchase POST failed. Reason: %s",
                resp["reason"])
        time.sleep(20)

        # check bob detected payment
        api_url = bob["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "EthRejectDirectOfflineTest - FAIL: Couldn't load order from Bob"
            )
        resp = json.loads(r.text)
        if len(resp["paymentAddressTransactions"]) <= 0:
            raise TestFailure(
                "EthRejectDirectOfflineTest - FAIL: Bob failed to detect his payment"
            )
        if resp["funded"] == False:
            raise TestFailure(
                "EthRejectDirectOfflineTest - FAIL: Bob incorrectly saved as unfunded"
            )
        if resp["state"] != "PENDING":
            raise TestFailure(
                "EthRejectDirectOfflineTest - FAIL: Bob purchase saved in incorrect state"
            )

        # startup alice again
        self.start_node(1, alice)
        time.sleep(60)

        # alice reject order
        api_url = alice["gateway_url"] + "ob/orderconfirmation"
        oc = {"orderId": orderId, "reject": True}
        r = requests.post(api_url, data=json.dumps(oc, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "EthRejectDirectOfflineTest - FAIL: Order confirmation post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "EthRejectDirectOfflineTest - FAIL: OrderConfirmation POST failed. Reason: %s",
                resp["reason"])
        time.sleep(120)

        # alice check order rejected correctly
        api_url = alice["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "EthRejectDirectOfflineTest - FAIL: Couldn't load order from Alice"
            )
        resp = json.loads(r.text)
        if resp["state"] != "DECLINED":
            raise TestFailure(
                "EthRejectDirectOfflineTest - FAIL: Alice failed to save as declined"
            )
        #if len(resp["paymentAddressTransactions"]) != 2:
        #    raise TestFailure("EthRejectDirectOfflineTest - FAIL: Alice failed to detect outgoing payment")

        # bob check order rejected correctly
        api_url = bob["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "EthRejectDirectOfflineTest - FAIL: Couldn't load order from Bob"
            )
        resp = json.loads(r.text)
        if resp["state"] != "DECLINED":
            raise TestFailure(
                "EthRejectDirectOfflineTest - FAIL: Bob failed to save as declined"
            )
        #if len(resp["paymentAddressTransactions"]) != 2:
        #    raise TestFailure("EthRejectDirectOfflineTest - FAIL: Bob failed to detect outgoing payment")

        time.sleep(2)

        # Check the funds moved into bob's wallet
        api_url = bob["gateway_url"] + "wallet/balance/T" + self.cointype
        r = requests.get(api_url)
        if r.status_code == 200:
            resp = json.loads(r.text)
            confirmed = int(resp["confirmed"])
            #unconfirmed = int(resp["unconfirmed"])
            #if confirmed <= 50 - int(payment_amount["amount"]):
            #    raise TestFailure("EthRejectDirectOfflineTest - FAIL: Bob failed to receive the multisig payout")
        else:
            raise TestFailure(
                "EthRejectDirectOfflineTest - FAIL: Failed to query Bob's balance"
            )

        print("EthRejectDirectOfflineTest - PASS")
Beispiel #21
0
    def run_test(self):
        alice = self.nodes[0]
        bob = self.nodes[1]
        charlie = self.nodes[2]

        # generate some coins and send them to bob
        time.sleep(4)
        api_url = bob["gateway_url"] + "wallet/address"
        r = requests.get(api_url)
        if r.status_code == 200:
            resp = json.loads(r.text)
            address = resp["address"]
        elif r.status_code == 404:
            raise TestFailure(
                "CompleteModeratedOnlineTest - FAIL: Address endpoint not found"
            )
        else:
            raise TestFailure(
                "CompleteModeratedOnlineTest - FAIL: Unknown response")
        self.send_bitcoin_cmd("sendtoaddress", address, 10)
        time.sleep(20)

        # create a profile for charlie
        pro = {"name": "Charlie"}
        api_url = charlie["gateway_url"] + "ob/profile"
        r = requests.post(api_url, data=json.dumps(pro, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "CompleteModeratedOnlineTest - FAIL: Profile post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "CompleteModeratedOnlineTest - FAIL: Profile POST failed. Reason: %s",
                resp["reason"])
        time.sleep(4)

        # make charlie a moderator
        with open('testdata/moderation.json') as listing_file:
            moderation_json = json.load(listing_file,
                                        object_pairs_hook=OrderedDict)
        api_url = charlie["gateway_url"] + "ob/moderator"
        r = requests.put(api_url, data=json.dumps(moderation_json, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "CompleteModeratedOnlineTest - FAIL: Moderator post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "CompleteModeratedOnlineTest - FAIL: Moderator POST failed. Reason: %s",
                resp["reason"])
        moderatorId = charlie["peerId"]
        time.sleep(4)

        # post listing to alice
        with open('testdata/listing.json') as listing_file:
            listing_json = json.load(listing_file,
                                     object_pairs_hook=OrderedDict)
        slug = listing_json["slug"]
        listing_json["moderators"] = [moderatorId]
        api_url = alice["gateway_url"] + "ob/listing"
        r = requests.post(api_url, data=json.dumps(listing_json, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "CompleteModeratedOnlineTest - FAIL: Listing post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "CompleteModeratedOnlineTest - FAIL: Listing POST failed. Reason: %s",
                resp["reason"])
        resp = json.loads(r.text)
        slug = resp["slug"]
        time.sleep(4)

        # get listing hash
        api_url = alice["gateway_url"] + "ipns/" + alice[
            "peerId"] + "/listings.json"
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "CompleteModeratedOnlineTest - FAIL: Couldn't get listing index"
            )
        resp = json.loads(r.text)
        listingId = resp[0]["hash"]

        # bob send order
        with open('testdata/order_direct.json') as order_file:
            order_json = json.load(order_file, object_pairs_hook=OrderedDict)
        order_json["items"][0]["listingHash"] = listingId
        order_json["moderator"] = moderatorId
        api_url = bob["gateway_url"] + "ob/purchase"
        r = requests.post(api_url, data=json.dumps(order_json, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "CompleteModeratedOnlineTest - FAIL: Purchase post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            self.print_logs(alice, "ob.log")
            raise TestFailure(
                "CompleteModeratedOnlineTest - FAIL: Purchase POST failed. Reason: %s",
                resp["reason"])
        resp = json.loads(r.text)
        orderId = resp["orderId"]
        payment_address = resp["paymentAddress"]
        payment_amount = resp["amount"]

        # check the purchase saved correctly
        api_url = bob["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "CompleteModeratedOnlineTest - FAIL: Couldn't load order from Bob"
            )
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_PAYMENT":
            raise TestFailure(
                "CompleteModeratedOnlineTest - FAIL: Bob purchase saved in incorrect state"
            )
        if resp["funded"] == True:
            raise TestFailure(
                "CompleteModeratedOnlineTest - FAIL: Bob incorrectly saved as funded"
            )

        # check the sale saved correctly
        api_url = alice["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "CompleteModeratedOnlineTest - FAIL: Couldn't load order from Alice"
            )
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_PAYMENT":
            raise TestFailure(
                "CompleteModeratedOnlineTest - FAIL: Alice purchase saved in incorrect state"
            )
        if resp["funded"] == True:
            raise TestFailure(
                "CompleteModeratedOnlineTest - FAIL: Alice incorrectly saved as funded"
            )

        # fund order
        spend = {
            "address": payment_address,
            "amount": payment_amount,
            "feeLevel": "NORMAL"
        }
        api_url = bob["gateway_url"] + "wallet/spend"
        r = requests.post(api_url, data=json.dumps(spend, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "CompleteModeratedOnlineTest - FAIL: Spend post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "CompleteModeratedOnlineTest - FAIL: Spend POST failed. Reason: %s",
                resp["reason"])
        time.sleep(20)

        # check bob detected payment
        api_url = bob["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "CompleteModeratedOnlineTest - FAIL: Couldn't load order from Bob"
            )
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_FULFILLMENT":
            raise TestFailure(
                "CompleteModeratedOnlineTest - FAIL: Bob failed to detect his payment"
            )
        if resp["funded"] == False:
            raise TestFailure(
                "CompleteModeratedOnlineTest - FAIL: Bob incorrectly saved as unfunded"
            )

        # check alice detected payment
        api_url = alice["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "CompleteModeratedOnlineTest - FAIL: Couldn't load order from Alice"
            )
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_FULFILLMENT":
            raise TestFailure(
                "CompleteModeratedOnlineTest - FAIL: Alice failed to detect payment"
            )
        if resp["funded"] == False:
            raise TestFailure(
                "CompleteModeratedOnlineTest - FAIL: Alice incorrectly saved as unfunded"
            )

        # alice send order fulfillment
        with open('testdata/fulfillment.json') as fulfillment_file:
            fulfillment_json = json.load(fulfillment_file,
                                         object_pairs_hook=OrderedDict)
        fulfillment_json["slug"] = slug
        fulfillment_json["orderId"] = orderId
        api_url = alice["gateway_url"] + "ob/orderfulfillment"
        r = requests.post(api_url, data=json.dumps(fulfillment_json, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "CompleteModeratedOnlineTest - FAIL: Fulfillment post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "CompleteModeratedOnlineTest - FAIL: Fulfillment POST failed. Reason: %s",
                resp["reason"])
        time.sleep(4)

        # check bob received fulfillment
        api_url = bob["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "CompleteModeratedOnlineTest - FAIL: Couldn't load order from Bob"
            )
        resp = json.loads(r.text)
        if resp["state"] != "FULFILLED":
            raise TestFailure(
                "CompleteModeratedOnlineTest - FAIL: Bob failed to detect order fulfillment"
            )

        # check alice set fulfillment correctly
        api_url = alice["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "CompleteModeratedOnlineTest - FAIL: Couldn't load order from Bob"
            )
        resp = json.loads(r.text)
        if resp["state"] != "FULFILLED":
            raise TestFailure(
                "CompleteModeratedOnlineTest - FAIL: Alice failed to order fulfillment"
            )

        # bob send order completion
        with open('testdata/completion.json') as completion_file:
            completion_json = json.load(completion_file,
                                        object_pairs_hook=OrderedDict)
        completion_json["orderId"] = orderId
        completion_json["ratings"][0]["slug"] = slug
        api_url = bob["gateway_url"] + "ob/ordercompletion"
        r = requests.post(api_url, data=json.dumps(completion_json, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "CompleteModeratedOnlineTest - FAIL: Completion post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "CompleteModeratedOnlineTest - FAIL: Completion POST failed. Reason: %s",
                resp["reason"])
        time.sleep(4)

        # check alice received completion
        api_url = alice["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "CompleteModeratedOnlineTest - FAIL: Couldn't load order from Alice"
            )
        resp = json.loads(r.text)
        if resp["state"] != "COMPLETED":
            raise TestFailure(
                "CompleteModeratedOnlineTest - FAIL: Alice failed to detect order completion"
            )

        # check bob set completion correctly
        api_url = bob["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "CompleteModeratedOnlineTest - FAIL: Couldn't load order from Bob"
            )
        resp = json.loads(r.text)
        if resp["state"] != "COMPLETED":
            raise TestFailure(
                "CompleteModeratedOnlineTest - FAIL: Bob failed to order completion"
            )

        # Check the funds moved into alice's wallet
        api_url = alice["gateway_url"] + "wallet/balance"
        r = requests.get(api_url)
        if r.status_code == 200:
            resp = json.loads(r.text)
            confirmed = int(resp["confirmed"])
            unconfirmed = int(resp["unconfirmed"])
            if confirmed + unconfirmed <= 0:
                raise TestFailure(
                    "RefundDirectTest - FAIL: Alice failed to receive the multisig payout"
                )
        else:
            raise TestFailure(
                "RefundDirectTest - FAIL: Failed to query Alice's balance")

        print("CompleteModeratedOnlineTest - PASS")
    def run_test(self):
        vendor = self.nodes[0]
        buyer = self.nodes[1]

        # generate some coins and send them to buyer
        time.sleep(4)
        api_url = buyer["gateway_url"] + "wallet/address"
        r = requests.get(api_url)
        if r.status_code == 200:
            resp = json.loads(r.text)
            address = resp["address"]
        elif r.status_code == 404:
            raise TestFailure(
                "PurchaseCryptoListingTest - FAIL: Address endpoint not found")
        else:
            raise TestFailure(
                "PurchaseCryptoListingTest - FAIL: Unknown response")
        self.send_bitcoin_cmd("sendtoaddress", address, 10)
        time.sleep(20)

        # post profile for vendor
        with open('testdata/profile.json') as profile_file:
            profile_json = json.load(profile_file,
                                     object_pairs_hook=OrderedDict)
        api_url = vendor["gateway_url"] + "ob/profile"
        requests.post(api_url, data=json.dumps(profile_json, indent=4))

        # post listing to vendor
        with open('testdata/listing_crypto.json') as listing_file:
            listing_json = json.load(listing_file,
                                     object_pairs_hook=OrderedDict)

        api_url = vendor["gateway_url"] + "ob/listing"
        r = requests.post(api_url, data=json.dumps(listing_json, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "PurchaseCryptoListingTest - FAIL: Listing post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "PurchaseCryptoListingTest - FAIL: Listing POST failed. Reason: %s",
                resp["reason"])
        slug = json.loads(r.text)["slug"]

        # check inventory
        api_url = vendor["gateway_url"] + "ob/inventory"
        r = requests.get(api_url, data=json.dumps(listing_json, indent=4))
        resp = json.loads(r.text)
        if r.status_code != 200:
            raise TestFailure(
                "PurchaseCryptoListingTest - FAIL: Inventory get endpoint failed"
            )
        if resp["ether"]["inventory"] != 350000000:
            raise TestFailure(
                "PurchaseCryptoListingTest - FAIL: Inventory incorrect: %d",
                resp["ether"]["inventory"])

        # get listing hash
        api_url = vendor["gateway_url"] + "ob/listings/" + vendor["peerId"]
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "PurchaseCryptoListingTest - FAIL: Couldn't get listing index")
        resp = json.loads(r.text)
        if resp[0]["coinType"] != "ETH":
            raise TestFailure(
                "PurchaseCryptoListingTest - FAIL: Vendor incorrectly saved listings.json without a coinType"
            )
        listingId = resp[0]["hash"]

        # buyer send order
        with open('testdata/order_crypto.json') as order_file:
            order_json = json.load(order_file, object_pairs_hook=OrderedDict)
        order_json["items"][0]["listingHash"] = listingId
        api_url = buyer["gateway_url"] + "ob/purchase"
        r = requests.post(api_url, data=json.dumps(order_json, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "PurchaseCryptoListingTest - FAIL: Purchase post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "PurchaseCryptoListingTest - FAIL: Purchase POST failed. Reason: %s",
                resp["reason"])
        resp = json.loads(r.text)
        orderId = resp["orderId"]
        payment_address = resp["paymentAddress"]
        payment_amount = resp["amount"]
        if payment_amount <= 0:
            raise TestFailure(
                "PurchaseCryptoListingTest - FAIL: Purchase POST failed: paymentAmount is <= 0"
            )

        # check the purchase saved correctly
        api_url = buyer["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "PurchaseCryptoListingTest - FAIL: Couldn't load order from Buyer"
            )
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_PAYMENT":
            raise TestFailure(
                "PurchaseCryptoListingTest - FAIL: Buyer purchase saved in incorrect state"
            )
        if resp["funded"] == True:
            raise TestFailure(
                "PurchaseCryptoListingTest - FAIL: Buyer incorrectly saved as funded"
            )
        if resp["contract"]["vendorListings"][0]["metadata"][
                "coinType"] != "ETH":
            raise TestFailure(
                "PurchaseCryptoListingTest - FAIL: Buyer incorrectly saved without a coinType"
            )
        if resp["contract"]["buyerOrder"]["items"][0][
                "paymentAddress"] != "crypto_payment_address":
            raise TestFailure(
                "PurchaseCryptoListingTest - FAIL: Buyer incorrectly saved without a paymentAddress"
            )

        # check the sale saved correctly
        api_url = vendor["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "PurchaseCryptoListingTest - FAIL: Couldn't load order from Vendor"
            )
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_PAYMENT":
            raise TestFailure(
                "PurchaseCryptoListingTest - FAIL: Vendor purchase saved in incorrect state"
            )
        if resp["funded"] == True:
            raise TestFailure(
                "PurchaseCryptoListingTest - FAIL: Vendor incorrectly saved as funded"
            )
        if resp["contract"]["vendorListings"][0]["metadata"][
                "coinType"] != "ETH":
            raise TestFailure(
                "PurchaseCryptoListingTest - FAIL: Vendor incorrectly saved without a coinType"
            )
        if resp["contract"]["buyerOrder"]["items"][0][
                "paymentAddress"] != "crypto_payment_address":
            raise TestFailure(
                "PurchaseCryptoListingTest - FAIL: Vendor incorrectly saved without a paymentAddress"
            )
        if resp["contract"]["buyerOrder"]["items"][0]["memo"] != "thanks!":
            raise TestFailure(
                "PurchaseCryptoListingTest - FAIL: Vendor incorrectly saved without a memo"
            )

        # fund order
        spend = {
            "address": payment_address,
            "amount": payment_amount,
            "feeLevel": "NORMAL"
        }
        api_url = buyer["gateway_url"] + "wallet/spend"
        r = requests.post(api_url, data=json.dumps(spend, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "PurchaseCryptoListingTest - FAIL: Spend post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "PurchaseCryptoListingTest - FAIL: Spend POST failed. Reason: %s",
                resp["reason"])
        time.sleep(20)

        # check buyer detected payment
        api_url = buyer["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "PurchaseCryptoListingTest - FAIL: Couldn't load order from Buyer"
            )
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_FULFILLMENT":
            raise TestFailure(
                "PurchaseCryptoListingTest - FAIL: Buyer failed to detect his payment"
            )
        if resp["funded"] == False:
            raise TestFailure(
                "PurchaseCryptoListingTest - FAIL: Buyer incorrectly saved as unfunded"
            )
        if resp["contract"]["vendorListings"][0]["metadata"][
                "coinType"] != "ETH":
            raise TestFailure(
                "PurchaseCryptoListingTest - FAIL: Buyer incorrectly saved without a coinType"
            )
        if resp["contract"]["buyerOrder"]["items"][0][
                "paymentAddress"] != "crypto_payment_address":
            raise TestFailure(
                "PurchaseCryptoListingTest - FAIL: Buyer incorrectly saved without a paymentAddress"
            )

        # check vendor detected payment
        api_url = vendor["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "PurchaseCryptoListingTest - FAIL: Couldn't load order from Vendor"
            )
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_FULFILLMENT":
            raise TestFailure(
                "PurchaseCryptoListingTest - FAIL: Vendor failed to detect payment"
            )
        if resp["funded"] == False:
            raise TestFailure(
                "PurchaseCryptoListingTest - FAIL: Vendor incorrectly saved as unfunded"
            )

        with open('testdata/fulfillment_crypto.json') as fulfillment_file:
            fulfillment_json = json.load(fulfillment_file,
                                         object_pairs_hook=OrderedDict)
        fulfillment_json["orderId"] = orderId
        fulfillment_json["slug"] = slug
        api_url = vendor["gateway_url"] + "ob/orderfulfillment"
        r = requests.post(api_url, data=json.dumps(fulfillment_json, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "PurchaseCryptoListingTest - FAIL: Fulfillment post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "PurchaseCryptoListingTest - FAIL: Fulfillment POST failed. Reason: %s",
                resp["reason"])

        # check buyer received fulfillment
        api_url = buyer["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "PurchaseCryptoListingTest - FAIL: Couldn't load order from Buyer"
            )
        resp = json.loads(r.text)
        if resp["state"] != "FULFILLED":
            raise TestFailure(
                "PurchaseCryptoListingTest - FAIL: Buyer failed to detect order fulfillment"
            )
        if resp["contract"]["vendorOrderFulfillment"][0][
                "cryptocurrencyDelivery"][0][
                    "transactionID"] != "crypto_transaction_id":
            raise TestFailure(
                "PurchaseCryptoListingTest - FAIL: Buyer failed to detect transactionID"
            )

        api_url = vendor["gateway_url"] + "ob/inventory"
        r = requests.get(api_url, data=json.dumps(listing_json, indent=4))
        resp = json.loads(r.text)
        if r.status_code != 200:
            raise TestFailure(
                "PurchaseCryptoListingTest - FAIL: Inventory get endpoint failed"
            )
        if resp["ether"]["inventory"] != 250000000:
            raise TestFailure(
                "PurchaseCryptoListingTest - FAIL: Inventory incorrect: %d",
                resp["ether"]["inventory"])

        print("PurchaseCryptoListingTest - PASS")
    def run_test(self):
        alice = self.nodes[0]
        bob = self.nodes[1]
        charlie = self.nodes[2]

        # generate some coins and send them to bob
        generated_coins = 10
        time.sleep(4)
        api_url = bob["gateway_url"] + "wallet/address"
        r = requests.get(api_url)
        if r.status_code == 200:
            resp = json.loads(r.text)
            address = resp["address"]
        elif r.status_code == 404:
            raise TestFailure(
                "CompleteDisputedTest - FAIL: Address endpoint not found")
        else:
            raise TestFailure("CompleteDisputedTest - FAIL: Unknown response")
        self.send_bitcoin_cmd("sendtoaddress", address, generated_coins)
        time.sleep(20)

        # create a profile for charlie
        pro = {"name": "Charlie"}
        api_url = charlie["gateway_url"] + "ob/profile"
        r = requests.post(api_url, data=json.dumps(pro, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "CompleteDisputedTest - FAIL: Profile post endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "CompleteDisputedTest - FAIL: Profile POST failed. Reason: %s",
                resp["reason"])
        time.sleep(4)

        # make charlie a moderator
        with open('testdata/moderation.json') as listing_file:
            moderation_json = json.load(listing_file,
                                        object_pairs_hook=OrderedDict)
        api_url = charlie["gateway_url"] + "ob/moderator"
        r = requests.put(api_url, data=json.dumps(moderation_json, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "CompleteDisputedTest - FAIL: Moderator post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "CompleteDisputedTest - FAIL: Moderator POST failed. Reason: %s",
                resp["reason"])
        moderatorId = charlie["peerId"]
        time.sleep(4)

        # post listing to alice
        with open('testdata/listing.json') as listing_file:
            listing_json = json.load(listing_file,
                                     object_pairs_hook=OrderedDict)

        listing_json["moderators"] = [moderatorId]
        api_url = alice["gateway_url"] + "ob/listing"
        r = requests.post(api_url, data=json.dumps(listing_json, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "CompleteDisputedTest - FAIL: Listing post endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "CompleteDisputedTest - FAIL: Listing POST failed. Reason: %s",
                resp["reason"])
        resp = json.loads(r.text)
        slug = resp["slug"]
        time.sleep(4)

        # get listing hash
        api_url = alice["gateway_url"] + "ipns/" + alice[
            "peerId"] + "/listings/index.json"
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "CompleteDisputedTest - FAIL: Couldn't get listing index")
        resp = json.loads(r.text)
        listingId = resp[0]["hash"]

        # bob send order
        with open('testdata/order_direct.json') as order_file:
            order_json = json.load(order_file, object_pairs_hook=OrderedDict)
        order_json["items"][0]["listingHash"] = listingId
        order_json["moderator"] = moderatorId
        api_url = bob["gateway_url"] + "ob/purchase"
        r = requests.post(api_url, data=json.dumps(order_json, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "CompleteDisputedTest - FAIL: Purchase post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            self.print_logs(alice, "ob.log")
            raise TestFailure(
                "CompleteDisputedTest - FAIL: Purchase POST failed. Reason: %s",
                resp["reason"])
        resp = json.loads(r.text)
        orderId = resp["orderId"]
        payment_address = resp["paymentAddress"]
        payment_amount = resp["amount"]

        # check the purchase saved correctly
        api_url = bob["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "CompleteDisputedTest - FAIL: Couldn't load order from Bob")
        resp = json.loads(r.text)
        if resp["state"] != "CONFIRMED":
            raise TestFailure(
                "CompleteDisputedTest - FAIL: Bob purchase saved in incorrect state"
            )
        if resp["funded"] == True:
            raise TestFailure(
                "CompleteDisputedTest - FAIL: Bob incorrectly saved as funded")

        # check the sale saved correctly
        api_url = alice["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "CompleteDisputedTest - FAIL: Couldn't load order from Alice")
        resp = json.loads(r.text)
        if resp["state"] != "CONFIRMED":
            raise TestFailure(
                "CompleteDisputedTest - FAIL: Alice purchase saved in incorrect state"
            )
        if resp["funded"] == True:
            raise TestFailure(
                "CompleteDisputedTest - FAIL: Alice incorrectly saved as funded"
            )

        # fund order
        spend = {
            "address": payment_address,
            "amount": payment_amount,
            "feeLevel": "NORMAL"
        }
        api_url = bob["gateway_url"] + "wallet/spend"
        r = requests.post(api_url, data=json.dumps(spend, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "CompleteDisputedTest - FAIL: Spend post endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "CompleteDisputedTest - FAIL: Spend POST failed. Reason: %s",
                resp["reason"])
        time.sleep(20)

        # check bob detected payment
        api_url = bob["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "CompleteDisputedTest - FAIL: Couldn't load order from Bob")
        resp = json.loads(r.text)
        if resp["state"] != "FUNDED":
            raise TestFailure(
                "CompleteDisputedTest - FAIL: Bob failed to detect his payment"
            )
        if resp["funded"] == False:
            raise TestFailure(
                "CompleteDisputedTest - FAIL: Bob incorrectly saved as unfunded"
            )

        # check alice detected payment
        api_url = alice["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "CompleteDisputedTest - FAIL: Couldn't load order from Alice")
        resp = json.loads(r.text)
        if resp["state"] != "FUNDED":
            raise TestFailure(
                "CompleteDisputedTest - FAIL: Alice failed to detect payment")
        if resp["funded"] == False:
            raise TestFailure(
                "CompleteDisputedTest - FAIL: Alice incorrectly saved as unfunded"
            )

        # Bob open dispute
        dispute = {"orderId": orderId, "claim": "Bastard ripped me off"}
        api_url = bob["gateway_url"] + "ob/opendispute/"
        r = requests.post(api_url, data=json.dumps(dispute, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "CompleteDisputedTest - FAIL: OpenDispute post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "CompleteDisputedTest - FAIL: OpenDispute POST failed. Reason: %s",
                resp["reason"])
        time.sleep(4)

        # Bob check dispute opened correctly
        api_url = bob["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "CompleteDisputedTest - FAIL: Couldn't load order from Bob")
        resp = json.loads(r.text)
        if resp["state"] != "DISPUTED":
            raise TestFailure(
                "CompleteDisputedTest - FAIL: Bob failed to detect his dispute"
            )

        # Alice check dispute opened correctly
        api_url = alice["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "CompleteDisputedTest - FAIL: Couldn't load order from Alice")
        resp = json.loads(r.text)
        if resp["state"] != "DISPUTED":
            raise TestFailure(
                "CompleteDisputedTest - FAIL: Alice failed to detect the dispute"
            )

        # Charlie check dispute opened correctly
        api_url = charlie["gateway_url"] + "ob/case/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "CompleteDisputedTest - FAIL: Couldn't load case from Clarlie")
        resp = json.loads(r.text, object_pairs_hook=OrderedDict)
        if resp["state"] != "DISPUTED":
            raise TestFailure(
                "CompleteDisputedTest - FAIL: Charlie failed to detect the dispute"
            )

        # Charlie close dispute
        dispute_resolution = {
            "OrderID": orderId,
            "Resolution": "I'm siding with Bob",
            "BuyerPercentage": 100,
            "VendorPercentage": 0
        }
        api_url = charlie["gateway_url"] + "ob/closedispute/"
        r = requests.post(api_url,
                          data=json.dumps(dispute_resolution, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "CompleteDisputedTest - FAIL: CloseDispute post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "CompleteDisputedTest - FAIL: CloseDispute POST failed. Reason: %s",
                resp["reason"])
        time.sleep(4)

        # Alice check dispute closed correctly
        api_url = alice["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "CompleteDisputedTest - FAIL: Couldn't load order from Alice")
        resp = json.loads(r.text)
        if resp["state"] != "DECIDED":
            self.print_logs(alice, "ob.log")
            raise TestFailure(
                "CompleteDisputedTest - FAIL: Alice failed to detect the dispute resolution"
            )

        # Bob check dispute closed correctly
        api_url = bob["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "CompleteDisputedTest - FAIL: Couldn't load order from Bob")
        resp = json.loads(r.text, object_pairs_hook=OrderedDict)
        if resp["state"] != "DECIDED":
            raise TestFailure(
                "CompleteDisputedTest - FAIL: Bob failed to detect the dispute resolution"
            )

        # Charlie check dispute closed correctly
        api_url = charlie["gateway_url"] + "ob/case/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "CompleteDisputedTest - FAIL: Couldn't load case from Charlie")
        resp = json.loads(r.text, object_pairs_hook=OrderedDict)
        if resp["state"] != "RESOLVED":
            raise TestFailure(
                "CompleteDisputedTest - FAIL: Charlie failed to detect the dispute resolution"
            )

        # Bob relase funds
        release = {
            "OrderID": orderId,
        }
        api_url = bob["gateway_url"] + "ob/releasefunds/"
        r = requests.post(api_url, data=json.dumps(release, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "CompleteDisputedTest - FAIL: ReleaseFunds post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "CompleteDisputedTest - FAIL: ReleaseFunds POST failed. Reason: %s",
                resp["reason"])
        time.sleep(20)

        # Check bob received payout
        api_url = bob["gateway_url"] + "wallet/balance"
        r = requests.get(api_url)
        if r.status_code == 200:
            resp = json.loads(r.text)
            confirmed = int(resp["confirmed"])
            unconfirmed = int(resp["unconfirmed"])
            if confirmed + unconfirmed <= (generated_coins *
                                           100000000) - payment_amount:
                raise TestFailure(
                    "CompleteDisputedTest - FAIL: Bob failed to detect dispute payout"
                )
        elif r.status_code == 404:
            raise TestFailure(
                "CompleteDisputedTest - FAIL: Receive coins endpoint not found"
            )
        else:
            raise TestFailure("CompleteDisputedTest - FAIL: Unknown response")

        # Bob check payout transaction recorded
        api_url = bob["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "CompleteDisputedTest - FAIL: Couldn't load order from Bob")
        resp = json.loads(r.text, object_pairs_hook=OrderedDict)
        if len(resp["transactions"]) != 2:
            raise TestFailure(
                "CompleteDisputedTest - FAIL: Bob failed to record payout transaction"
            )
        if resp["state"] != "RESOLVED":
            raise TestFailure(
                "CompleteDisputedTest - FAIL: Bob failed to set state to RESOLVED"
            )

        # Alice check payout transaction recorded
        api_url = alice["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "CompleteDisputedTest - FAIL: Couldn't load order from Alice")
        resp = json.loads(r.text, object_pairs_hook=OrderedDict)
        if len(resp["transactions"]) != 2:
            raise TestFailure(
                "CompleteDisputedTest - FAIL: Alice failed to record payout transaction"
            )
        if resp["state"] != "RESOLVED":
            raise TestFailure(
                "CompleteDisputedTest - FAIL: Alice failed to set state to RESOLVED"
            )

        # bob send order completion
        oc = {
            "orderId":
            orderId,
            "ratings": [{
                "slug": slug,
                "overall": 4,
                "quality": 5,
                "description": 5,
                "customerService": 4,
                "deliverySpeed": 3,
                "Review": "I love it!"
            }]
        }
        api_url = bob["gateway_url"] + "ob/ordercompletion"
        r = requests.post(api_url, data=json.dumps(oc, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "CompleteDirectOnlineTest - FAIL: Completion post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "CompleteDirectOnlineTest - FAIL: Completion POST failed. Reason: %s",
                resp["reason"])
        time.sleep(4)

        # check alice received completion
        api_url = alice["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "CompleteDirectOnlineTest - FAIL: Couldn't load order from Alice"
            )
        resp = json.loads(r.text)
        if resp["state"] != "COMPLETE":
            raise TestFailure(
                "CompleteDirectOnlineTest - FAIL: Alice failed to detect order completion"
            )

        # check bob set completion correctly
        api_url = bob["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "CompleteDirectOnlineTest - FAIL: Couldn't load order from Bob"
            )
        resp = json.loads(r.text)
        if resp["state"] != "COMPLETE":
            raise TestFailure(
                "CompleteDirectOnlineTest - FAIL: Bob failed to order completion"
            )

        print("CompleteDisputedTest - PASS")
Beispiel #24
0
    def run_test(self):
        alice = self.nodes[1]
        bob = self.nodes[2]

        # generate some coins and send them to bob
        time.sleep(4)
        api_url = bob["gateway_url"] + "wallet/address/" + self.cointype
        r = requests.get(api_url)
        if r.status_code == 200:
            resp = json.loads(r.text)
            address = resp["address"]
        elif r.status_code == 404:
            raise TestFailure(
                "EthCompleteDirectOnlineTest - FAIL: Address endpoint not found"
            )
        else:
            raise TestFailure(
                "EthCompleteDirectOnlineTest - FAIL: Unknown response")
        time.sleep(20)

        # post profile for alice
        with open('testdata/profile.json') as profile_file:
            profile_json = json.load(profile_file,
                                     object_pairs_hook=OrderedDict)
        api_url = alice["gateway_url"] + "ob/profile"
        requests.post(api_url, data=json.dumps(profile_json, indent=4))

        # post listing to alice
        with open('testdata/eth_listing.json') as listing_file:
            listing_json = json.load(listing_file,
                                     object_pairs_hook=OrderedDict)
        listing_json["item"]["priceCurrency"]["code"] = "T" + self.cointype
        listing_json["metadata"]["acceptedCurrencies"] = ["T" + self.cointype]
        api_url = alice["gateway_url"] + "ob/listing"
        r = requests.post(api_url, data=json.dumps(listing_json, indent=4))
        print("api_url : ", api_url)
        print(json.dumps(listing_json, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "EthCompleteDirectOnlineTest - FAIL: Listing post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "EthCompleteDirectOnlineTest - FAIL: Listing POST failed. Reason: %s",
                resp["reason"])
        resp = json.loads(r.text)
        slug = resp["slug"]
        time.sleep(4)

        # get listing hash
        api_url = alice["gateway_url"] + "ob/listings/" + alice["peerId"]
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "EthCompleteDirectOnlineTest - FAIL: Couldn't get listing index"
            )
        resp = json.loads(r.text)
        listingId = resp[0]["hash"]

        # bob send order
        with open('testdata/order_direct.json') as order_file:
            order_json = json.load(order_file, object_pairs_hook=OrderedDict)
        order_json["items"][0]["listingHash"] = listingId
        order_json["paymentCoin"] = "T" + self.cointype
        api_url = bob["gateway_url"] + "ob/purchase"
        r = requests.post(api_url, data=json.dumps(order_json, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "EthCompleteDirectOnlineTest - FAIL: Purchase post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "EthCompleteDirectOnlineTest - FAIL: Purchase POST failed. Reason: %s",
                resp["reason"])
        resp = json.loads(r.text)
        orderId = resp["orderId"]
        payment_address = resp["paymentAddress"]
        payment_amount = resp["amount"]

        # check the purchase saved correctly
        api_url = bob["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "EthCompleteDirectOnlineTest - FAIL: Couldn't load order from Bob"
            )
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_PAYMENT":
            raise TestFailure(
                "EthCompleteDirectOnlineTest - FAIL: Bob purchase saved in incorrect state"
            )
        if resp["funded"] == True:
            raise TestFailure(
                "EthCompleteDirectOnlineTest - FAIL: Bob incorrectly saved as funded"
            )

        # check the sale saved correctly
        api_url = alice["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "EthCompleteDirectOnlineTest - FAIL: Couldn't load order from Alice"
            )
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_PAYMENT":
            raise TestFailure(
                "EthCompleteDirectOnlineTest - FAIL: Alice purchase saved in incorrect state"
            )
        if resp["funded"] == True:
            raise TestFailure(
                "EthCompleteDirectOnlineTest - FAIL: Alice incorrectly saved as funded"
            )

        # fund order
        spend = {
            "currencyCode": "T" + self.cointype,
            "address": payment_address,
            "amount": payment_amount["amount"],
            "feeLevel": "NORMAL",
            "requireAssociateOrder": True,
            "orderID": orderId
        }
        api_url = bob["gateway_url"] + "ob/orderspend"
        print("################################")
        print("before spend post : ", api_url)
        print(json.dumps(spend, indent=4))
        r = requests.post(api_url, data=json.dumps(spend, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "EthCompleteDirectOnlineTest - FAIL: Spend post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "EthCompleteDirectOnlineTest - FAIL: Spend POST failed. Reason: %s",
                resp["reason"])
        time.sleep(60)

        # check bob detected payment
        api_url = bob["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "EthCompleteDirectOnlineTest - FAIL: Couldn't load order from Bob"
            )
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_FULFILLMENT":
            raise TestFailure(
                "EthCompleteDirectOnlineTest - FAIL: Bob failed to detect his payment"
            )
        if resp["funded"] == False:
            raise TestFailure(
                "EthCompleteDirectOnlineTest - FAIL: Bob incorrectly saved as unfunded"
            )

        # check alice detected payment
        api_url = alice["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "EthCompleteDirectOnlineTest - FAIL: Couldn't load order from Alice"
            )
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_FULFILLMENT":
            raise TestFailure(
                "EthCompleteDirectOnlineTest - FAIL: Alice failed to detect payment"
            )
        if resp["funded"] == False:
            raise TestFailure(
                "EthCompleteDirectOnlineTest - FAIL: Alice incorrectly saved as unfunded"
            )

        # alice send order fulfillment
        with open('testdata/fulfillment.json') as fulfillment_file:
            fulfillment_json = json.load(fulfillment_file,
                                         object_pairs_hook=OrderedDict)
        fulfillment_json["orderId"] = orderId
        fulfillment_json["slug"] = slug
        api_url = alice["gateway_url"] + "ob/orderfulfillment"
        r = requests.post(api_url, data=json.dumps(fulfillment_json, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "EthCompleteDirectOnlineTest - FAIL: Fulfillment post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "EthCompleteDirectOnlineTest - FAIL: Fulfillment POST failed. Reason: %s",
                resp["reason"])
        time.sleep(5)

        # check bob received fulfillment
        api_url = bob["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "EthCompleteDirectOnlineTest - FAIL: Couldn't load order from Bob"
            )
        resp = json.loads(r.text)
        if resp["state"] != "FULFILLED":
            raise TestFailure(
                "EthCompleteDirectOnlineTest - FAIL: Bob failed to detect order fulfillment"
            )

        # check alice set fulfillment correctly
        api_url = alice["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "EthCompleteDirectOnlineTest - FAIL: Couldn't load order from Bob"
            )
        resp = json.loads(r.text)
        if resp["state"] != "FULFILLED":
            raise TestFailure(
                "EthCompleteDirectOnlineTest - FAIL: Alice failed to order fulfillment"
            )

        # bob send order completion
        oc = {
            "orderId":
            orderId,
            "ratings": [{
                "slug": slug,
                "overall": 4,
                "quality": 5,
                "description": 5,
                "customerService": 4,
                "deliverySpeed": 3,
                "review": "I love it!"
            }]
        }
        api_url = bob["gateway_url"] + "ob/ordercompletion"
        r = requests.post(api_url, data=json.dumps(oc, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "EthCompleteDirectOnlineTest - FAIL: Completion post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "EthCompleteDirectOnlineTest - FAIL: Completion POST failed. Reason: %s",
                resp["reason"])
        time.sleep(4)

        # check alice received completion
        api_url = alice["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "EthCompleteDirectOnlineTest - FAIL: Couldn't load order from Alice"
            )
        resp = json.loads(r.text)
        if resp["state"] != "COMPLETED":
            raise TestFailure(
                "EthCompleteDirectOnlineTest - FAIL: Alice failed to detect order completion"
            )

        # check bob set completion correctly
        api_url = bob["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "EthCompleteDirectOnlineTest - FAIL: Couldn't load order from Bob"
            )
        resp = json.loads(r.text)
        if resp["state"] != "COMPLETED":
            raise TestFailure(
                "EthCompleteDirectOnlineTest - FAIL: Bob failed to order completion"
            )

        print("EthCompleteDirectOnlineTest - PASS")
Beispiel #25
0
    def run_test(self):
        alice = self.nodes[0]
        bob = self.nodes[1]

        alice_id = alice["peerId"]
        bob_id = bob["peerId"]

        # shutdown bob
        api_url = bob["gateway_url"] + "ob/shutdown"
        requests.post(api_url, data="")
        time.sleep(12)

        # alice send message
        message = {
            "subject": "",
            "message": "You have the stuff??",
            "peerId": bob_id
        }
        api_url = alice["gateway_url"] + "ob/chat"
        r = requests.post(api_url, data=json.dumps(message, indent=4))
        if r.status_code == 404:
            raise TestFailure("ChatOfflineTest - FAIL: Chat message post endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure("ChatOfflineTest - FAIL: Chat message POST failed. Reason: %s", resp["reason"])

        # check alice saved message correctly
        api_url = alice["gateway_url"] + "ob/chatmessages/" + bob_id
        r = requests.get(api_url)
        if r.status_code == 404:
            raise TestFailure("ChatOfflineTest - FAIL: Chat messages GET endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure("ChatOfflineTest - FAIL: Chat messages GET failed. Reason: %s", resp["reason"])
        resp = json.loads(r.text)
        if len(resp) != 1:
            raise TestFailure("ChatOfflineTest - FAIL: Did not record outgoing message")

        # check alice saved conversation correctly
        api_url = alice["gateway_url"] + "ob/chatconversations/"
        r = requests.get(api_url)
        if r.status_code == 404:
            raise TestFailure("ChatOfflineTest - FAIL: Chat messages GET endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure("ChatOfflineTest - FAIL: Chat messages GET failed. Reason: %s", resp["reason"])
        resp = json.loads(r.text)
        if len(resp) != 1:
            raise TestFailure("ChatOfflineTest - FAIL: Did not record outgoing message")
        if resp[0]["peerId"] != bob_id:
            raise TestFailure("ChatOfflineTest - FAIL: Did not record new conversation")

        # startup bob again
        self.start_node(bob)
        time.sleep(45)

        # check bob saved message correctly
        api_url = bob["gateway_url"] + "ob/chatmessages/" + alice_id
        r = requests.get(api_url)
        if r.status_code == 404:
            raise TestFailure("ChatOfflineTest - FAIL: Chat messages GET endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure("ChatOfflineTest - FAIL: Chat messages GET failed. Reason: %s", resp["reason"])
        resp = json.loads(r.text)
        if len(resp) != 1:
            raise TestFailure("ChatOfflineTest - FAIL: Did not record outgoing message")

        # check bob saved conversation correctly
        api_url = bob["gateway_url"] + "ob/chatconversations/"
        r = requests.get(api_url)
        if r.status_code == 404:
            raise TestFailure("ChatOfflineTest - FAIL: Chat messages GET endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure("ChatOfflineTest - FAIL: Chat messages GET failed. Reason: %s", resp["reason"])
        resp = json.loads(r.text)
        if len(resp) != 1:
            raise TestFailure("ChatOfflineTest - FAIL: Did not record outgoing message")
        if resp[0]["peerId"] != alice_id:
            raise TestFailure("ChatOfflineTest - FAIL: Did not record new conversation")

        # alice mark as read
        message = {
            "peerId": bob_id
        }
        api_url = alice["gateway_url"] + "ob/markchatasread"
        r = requests.post(api_url, data=json.dumps(message, indent=4))
        if r.status_code == 404:
            raise TestFailure("ChatOfflineTest - FAIL: Chat markasread post endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure("ChatOfflineTest - FAIL: Chat markasread POST failed. Reason: %s", resp["reason"])

        # check alice marked as read correctly
        api_url = alice["gateway_url"] + "ob/chatconversations/" + bob_id
        r = requests.get(api_url)
        if r.status_code == 404:
            raise TestFailure("ChatOfflineTest - FAIL: Chat conversations GET endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure("ChatOfflineTest - FAIL: Chat conversations GET failed. Reason: %s", resp["reason"])
        resp = json.loads(r.text)
        if len(resp) != 1:
            raise TestFailure("ChatOfflineTest - FAIL: Did not record outgoing message")
        if resp[0]["unread"] != 0:
            raise TestFailure("ChatOfflineTest - FAIL: Did not mark message as read")

        print("ChatOfflineTest - PASS")
Beispiel #26
0
    def run_test(self):
        alice = self.nodes[0]
        bob = self.nodes[1]
        charlie = self.nodes[2]

        # generate some coins and send them to bob
        time.sleep(4)
        api_url = bob["gateway_url"] + "wallet/address"
        r = requests.get(api_url)
        if r.status_code == 200:
            resp = json.loads(r.text)
            address = resp["address"]
        elif r.status_code == 404:
            raise TestFailure(
                "PurchaseModeratedOnlineTest - FAIL: Address endpoint not found"
            )
        else:
            raise TestFailure(
                "PurchaseModeratedOnlineTest - FAIL: Unknown response")
        self.send_bitcoin_cmd("sendtoaddress", address, 10)
        time.sleep(20)

        # create a profile for charlie
        pro = {"name": "Charlie"}
        api_url = charlie["gateway_url"] + "ob/profile"
        r = requests.post(api_url, data=json.dumps(pro, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "PurchaseModeratedOnlineTest - FAIL: Profile post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "PurchaseModeratedOnlineTest - FAIL: Profile POST failed. Reason: %s",
                resp["reason"])
        time.sleep(4)

        # make charlie a moderator
        with open('testdata/moderation.json') as listing_file:
            moderation_json = json.load(listing_file,
                                        object_pairs_hook=OrderedDict)
        api_url = charlie["gateway_url"] + "ob/moderator"
        r = requests.put(api_url, data=json.dumps(moderation_json, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "PurchaseModeratedOnlineTest - FAIL: Moderator post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "PurchaseModeratedOnlineTest - FAIL: Moderator POST failed. Reason: %s",
                resp["reason"])
        moderatorId = charlie["peerId"]
        time.sleep(4)

        # post listing to alice
        with open('testdata/listing.json') as listing_file:
            listing_json = json.load(listing_file,
                                     object_pairs_hook=OrderedDict)

        listing_json["listing"]["moderators"] = [moderatorId]
        api_url = alice["gateway_url"] + "ob/listing"
        r = requests.post(api_url, data=json.dumps(listing_json, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "PurchaseModeratedOnlineTest - FAIL: Listing post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "PurchaseModeratedOnlineTest - FAIL: Listing POST failed. Reason: %s",
                resp["reason"])
        time.sleep(4)

        # get listing hash
        api_url = alice["gateway_url"] + "ipns/" + alice[
            "peerId"] + "/listings/index.json"
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "PurchaseModeratedOnlineTest - FAIL: Couldn't get listing index"
            )
        resp = json.loads(r.text)
        listingId = resp[0]["hash"]

        # bob send order
        with open('testdata/order_direct.json') as order_file:
            order_json = json.load(order_file, object_pairs_hook=OrderedDict)
        order_json["items"][0]["listingHash"] = listingId
        order_json["moderator"] = moderatorId
        api_url = bob["gateway_url"] + "ob/purchase"
        r = requests.post(api_url, data=json.dumps(order_json, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "PurchaseModeratedOnlineTest - FAIL: Purchase post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            self.print_logs(alice, "ob.log")
            raise TestFailure(
                "PurchaseModeratedOnlineTest - FAIL: Purchase POST failed. Reason: %s",
                resp["reason"])
        resp = json.loads(r.text)
        orderId = resp["orderId"]
        payment_address = resp["paymentAddress"]
        payment_amount = resp["amount"]

        # check the purchase saved correctly
        api_url = bob["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "PurchaseModeratedOnlineTest - FAIL: Couldn't load order from Bob"
            )
        resp = json.loads(r.text)
        if resp["state"] != "CONFIRMED":
            raise TestFailure(
                "PurchaseModeratedOnlineTest - FAIL: Bob purchase saved in incorrect state"
            )
        if resp["funded"] == True:
            raise TestFailure(
                "PurchaseModeratedOnlineTest - FAIL: Bob incorrectly saved as funded"
            )

        # check the sale saved correctly
        api_url = alice["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "PurchaseModeratedOnlineTest - FAIL: Couldn't load order from Alice"
            )
        resp = json.loads(r.text)
        if resp["state"] != "CONFIRMED":
            raise TestFailure(
                "PurchaseModeratedOnlineTest - FAIL: Alice purchase saved in incorrect state"
            )
        if resp["funded"] == True:
            raise TestFailure(
                "PurchaseModeratedOnlineTest - FAIL: Alice incorrectly saved as funded"
            )

        # fund order
        spend = {
            "address": payment_address,
            "amount": payment_amount,
            "feeLevel": "NORMAL"
        }
        api_url = bob["gateway_url"] + "wallet/spend"
        r = requests.post(api_url, data=json.dumps(spend, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "PurchaseModeratedOnlineTest - FAIL: Spend post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "PurchaseModeratedOnlineTest - FAIL: Spend POST failed. Reason: %s",
                resp["reason"])
        time.sleep(20)

        # check bob detected payment
        api_url = bob["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "PurchaseModeratedOnlineTest - FAIL: Couldn't load order from Bob"
            )
        resp = json.loads(r.text)
        if resp["state"] != "FUNDED":
            raise TestFailure(
                "PurchaseModeratedOnlineTest - FAIL: Bob failed to detect his payment"
            )
        if resp["funded"] == False:
            raise TestFailure(
                "PurchaseModeratedOnlineTest - FAIL: Bob incorrectly saved as unfunded"
            )

        # check alice detected payment
        api_url = alice["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "PurchaseModeratedOnlineTest - FAIL: Couldn't load order from Alice"
            )
        resp = json.loads(r.text)
        if resp["state"] != "FUNDED":
            raise TestFailure(
                "PurchaseModeratedOnlineTest - FAIL: Alice failed to detect payment"
            )
        if resp["funded"] == False:
            raise TestFailure(
                "PurchaseModeratedOnlineTest - FAIL: Alice incorrectly saved as unfunded"
            )

        print("PurchaseModeratedOnlineTest - PASS")