Beispiel #1
0
    def run_test(self):
        time.sleep(4)
        api_url = self.nodes[0]["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(
                "ReceiveCoinsTest - FAIL: Address endpoint not found")
        else:
            raise TestFailure("ReceiveCoinsTest - FAIL: Unknown response")
        self.send_bitcoin_cmd("sendtoaddress", address, 10)
        time.sleep(20)
        api_url = self.nodes[0]["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("ReceiveCoinsTest - FAIL: Wallet is empty")
        elif r.status_code == 404:
            raise TestFailure(
                "ReceiveCoinsTest - FAIL: Receive coins endpoint not found")
        else:
            raise TestFailure("ReceiveCoinsTest - FAIL: Unknown response")

        print("ReceiveCoinsTest - PASS")
 def run_test(self):
     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"
     api_url = self.nodes[0]["gateway_url"] + "ob/listing"
     r = requests.post(api_url, data=json.dumps(listing_json, indent=4))
     if r.status_code == 404:
         raise TestFailure("UploadListingTest - FAIL: Listing post endpoint not found")
     elif r.status_code != 200:
         resp = json.loads(r.text)
         raise TestFailure("UploadListingTest - FAIL: Listing POST failed. Reason: %s", resp["reason"])
     api_url = self.nodes[0]["gateway_url"] + "ob/inventory"
     r = requests.get(api_url)
     if r.status_code == 200:
         resp = json.loads(r.text)
         if len(resp) == 8:
             print("UploadListingTest - PASS")
         else:
             raise TestFailure("UploadListingTest - FAIL: Returned incorrect amount of inventory")
     elif r.status_code == 404:
         raise TestFailure("UploadListingTest - FAIL: Listing post endpoint not found")
     else:
         resp = json.loads(r.text)
         raise TestFailure("UploadListingTest - FAIL: Listing POST failed. Reason: %s", resp["reason"])
 def run_test(self):
     with open('testdata/listing.json') as listing_file:
         listing_json = json.load(listing_file, object_pairs_hook=OrderedDict)
     api_url = self.nodes[0]["gateway_url"] + "ob/listing"
     r = requests.post(api_url, data=json.dumps(listing_json, indent=4))
     if r.status_code == 200:
         print("UploadListingTest - PASS")
     elif r.status_code == 404:
         raise TestFailure("UploadListingTest - FAIL: Listing post endpoint not found")
     else:
         resp = json.loads(r.text)
         raise TestFailure("UploadListingTest - FAIL: Listing POST failed. Reason: %s", resp["reason"])
    def run_test(self):
        alice = self.nodes[1]
        api_url = alice["gateway_url"] + "ob/profile"
        not_found = TestFailure(
            "PatchProfileTest - FAIL: Profile post endpoint not found")

        # create profile
        pro = {"name": "Alice", "nsfw": True, "about": "some stuff"}
        r = requests.post(api_url, data=json.dumps(pro, indent=4))
        if r.status_code == 404:
            raise not_found
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "PatchProfileTest - FAIL: Profile POST failed. Reason: %s",
                resp["reason"])
        time.sleep(4)

        # patch profile
        pro_patch = {"nsfw": False, "about": "new stuff"}
        r = requests.patch(api_url, data=json.dumps(pro_patch, indent=4))
        if r.status_code == 404:
            raise not_found
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "PatchProfileTest - FAIL: Profile PATCH failed. Reason: %s",
                resp["reason"])

        # check profile
        r = requests.get(api_url)
        if r.status_code == 404:
            raise not_found
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "PatchProfileTest - FAIL: Profile GET failed. Reason: %s",
                resp["reason"])
        else:
            resp = json.loads(r.text)
            if resp["name"] != "Alice" or resp["nsfw"] != False or resp[
                    "about"] != "new stuff":
                raise TestFailure(
                    "PatchProfileTest - FAIL: Incorrect result of profile PATCH"
                )

        print("PatchProfileTest - PASS")
Beispiel #5
0
    def run_test(self):
        node = self.nodes[0]

        # no listings POSTed
        api_url = node["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"
        api_url = node["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
        api_url = node["gateway_url"] + "ob/listings"
        r = requests.get(api_url)
        if r.status_code == 200:
            if len(json.loads(r.text)) == 1:
                print("ListingsTest - PASS")
            else:
                raise TestFailure(
                    "ListingsTest - FAIL: One listing 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"])
 def run_test(self):
     with open('testdata/'+ self.vendor_version +'/listing.json') as listing_file:
         listing_json = json.load(listing_file, object_pairs_hook=OrderedDict)
     if self.vendor_version == "v4":
         listing_json["metadata"]["priceCurrency"] = "t" + self.cointype
     else:
         listing_json["item"]["priceCurrency"]["code"] = "t" + self.cointype
         listing_json["item"]["priceCurrency"]["divisibility"] = 8
     listing_json["metadata"]["acceptedCurrencies"] = ["t" + self.cointype]
     api_url = self.nodes[1]["gateway_url"] + "ob/listing"
     r = requests.post(api_url, data=json.dumps(listing_json, indent=4))
     if r.status_code == 404:
         raise TestFailure("UploadListingTest - FAIL: Listing post endpoint not found")
     elif r.status_code != 200:
         resp = json.loads(r.text)
         raise TestFailure("UploadListingTest - FAIL: Listing POST failed. Reason: %s", resp["reason"])
     api_url = self.nodes[1]["gateway_url"] + "ob/inventory"
     r = requests.get(api_url)
     if r.status_code == 200:
         resp = json.loads(r.text)
         inv = resp["ron-swanson-tshirt"]
         if inv == None:
             raise TestFailure("UploadListingTest - FAIL: Did not return inventory for listing")
         if int(inv["inventory"]) != 213:
             raise TestFailure("UploadListingTest - FAIL: Returned incorrect amount of inventory: %d", inv["inventory"])
     elif r.status_code == 404:
         raise TestFailure("UploadListingTest - FAIL: Listing post endpoint not found")
     else:
         resp = json.loads(r.text)
         raise TestFailure("UploadListingTest - FAIL: Listing POST failed. Reason: %s", resp["reason"])
     print("UploadListingTest - PASS")
Beispiel #7
0
    def run_test(self):
        alice = self.nodes[0]
        bob = self.nodes[1]

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

        # 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(
                "ChatTest - FAIL: Chat message post endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "ChatTest - 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(
                "ChatTest - FAIL: Chat messages GET endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "ChatTest - FAIL: Chat messages GET failed. Reason: %s",
                resp["reason"])
        resp = json.loads(r.text)
        if len(resp) != 1:
            raise TestFailure(
                "ChatTest - 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(
                "ChatTest - FAIL: Chat messages GET endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "ChatTest - FAIL: Chat messages GET failed. Reason: %s",
                resp["reason"])
        resp = json.loads(r.text)
        if len(resp) != 1:
            raise TestFailure(
                "ChatTest - FAIL: Did not record outgoing message")
        if resp[0]["peerId"] != bob_id:
            raise TestFailure(
                "ChatTest - FAIL: Did not record new conversation")

        # 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(
                "ChatTest - FAIL: Chat messages GET endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "ChatTest - FAIL: Chat messages GET failed. Reason: %s",
                resp["reason"])
        resp = json.loads(r.text)
        if len(resp) != 1:
            raise TestFailure(
                "ChatTest - 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(
                "ChatTest - FAIL: Chat messages GET endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "ChatTest - FAIL: Chat messages GET failed. Reason: %s",
                resp["reason"])
        resp = json.loads(r.text)
        if len(resp) != 1:
            raise TestFailure(
                "ChatTest - FAIL: Did not record outgoing message")
        if resp[0]["peerId"] != alice_id:
            raise TestFailure(
                "ChatTest - FAIL: Did not record new conversation")

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

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

        print("ChatTest - PASS")
    def run_test(self):
        alice = self.nodes[0]
        bob = self.nodes[1]
        charlie = self.nodes[1]
        time.sleep(4)

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

        # send coins to alice
        api_url = alice["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("SendStealthTest - FAIL: Address endpoint not found")
        else:
            raise TestFailure("SendStealthTest - FAIL: Unknown response")
        self.send_bitcoin_cmd("sendtoaddress", address, 10)
        time.sleep(20)

        # get charlie address
        api_url = charlie["gateway_url"] + "wallet/address"
        r = requests.get(api_url)
        if r.status_code == 200:
            resp = json.loads(r.text)
            charlie_address = resp["address"]
        elif r.status_code == 404:
            raise TestFailure("SendStealthTest - FAIL: Address endpoint not found")
        else:
            raise TestFailure("SendStealthTest - FAIL: Unknown response")

        # check alice balance
        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("SendStealthTest - FAIL: Wallet is empty")
        elif r.status_code == 404:
            raise TestFailure("SendStealthTest - FAIL: Receive coins endpoint not found")
        else:
            raise TestFailure("SendStealthTest - FAIL: Unknown response")
        self.send_bitcoin_cmd("generate", 1)
        time.sleep(3)

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

        # check alice balance
        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 >= 1000000000 - payment_amount:
                raise TestFailure("SendStealthTest - FAIL: Alice failed to record spend")
        elif r.status_code == 404:
            raise TestFailure("SendStealthTest - FAIL: Receive coins endpoint not found")
        else:
            raise TestFailure("SendStealthTest - FAIL: Unknown response")

        # check bob balance
        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 <= 0:
                raise TestFailure("SendStealthTest - FAIL: Bob failed to detect payment")
        elif r.status_code == 404:
            raise TestFailure("SendStealthTest - FAIL: Receive coins endpoint not found")
        else:
            raise TestFailure("SendStealthTest - FAIL: Unknown response")

        # send to charlie
        charlie_payment_amount = 5000
        spend = {
            "address": charlie_address,
            "amount": charlie_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("SendStealthTest - FAIL: Spend post endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure("SendStealthTest - FAIL: Purchase POST failed. Reason: %s", resp["reason"])
        time.sleep(20)

        # check bob balance
        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 >= payment_amount - charlie_payment_amount:
                raise TestFailure("SendStealthTest - FAIL: Bob failed to record spend")
        elif r.status_code == 404:
            raise TestFailure("SendStealthTest - FAIL: Receive coins endpoint not found")
        else:
            raise TestFailure("SendStealthTest - FAIL: Unknown response")

        # check charlie balance
        api_url = charlie["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("SendStealthTest - FAIL: Charlie failed to detect payment")
        elif r.status_code == 404:
            raise TestFailure("SendStealthTest - FAIL: Receive coins endpoint not found")
        else:
            raise TestFailure("SendStealthTest - FAIL: Unknown response")

        print("SendStealthTest - 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
        print("bob's locn : ", api_url)
        r = requests.get(api_url)
        if r.status_code == 200:
            resp = json.loads(r.text)
            address = resp["address"]
            print("bob's addr : ", address)
        elif r.status_code == 404:
            raise TestFailure("EthEscrowTimeoutRelease - FAIL: Address endpoint not found")
        else:
            raise TestFailure("EthEscrowTimeoutRelease - 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("EthEscrowTimeoutRelease - FAIL: Profile post endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure("EthEscrowTimeoutRelease - 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("EthEscrowTimeoutRelease - FAIL: Moderator post endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure("EthEscrowTimeoutRelease - 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]
        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("EthEscrowTimeoutRelease - FAIL: Listing post endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure("EthEscrowTimeoutRelease - 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("EthEscrowTimeoutRelease - 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("EthEscrowTimeoutRelease - FAIL: Purchase post endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            self.print_logs(alice, "ob.log")
            raise TestFailure("EthEscrowTimeoutRelease - 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("EthEscrowTimeoutRelease - FAIL: Couldn't load order from Bob")
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_PAYMENT":
            raise TestFailure("EthEscrowTimeoutRelease - FAIL: Bob purchase saved in incorrect state")
        if resp["funded"] == True:
            raise TestFailure("EthEscrowTimeoutRelease - 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("EthEscrowTimeoutRelease - FAIL: Couldn't load order from Alice")
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_PAYMENT":
            raise TestFailure("EthEscrowTimeoutRelease - FAIL: Alice purchase saved in incorrect state")
        if resp["funded"] == True:
            raise TestFailure("EthEscrowTimeoutRelease - 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("EthEscrowTimeoutRelease - FAIL: Spend post endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure("EthEscrowTimeoutRelease - 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("EthEscrowTimeoutRelease - FAIL: Couldn't load order from Bob")
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_FULFILLMENT":
            raise TestFailure("EthEscrowTimeoutRelease - FAIL: Bob failed to detect his payment")
        if resp["funded"] == False:
            raise TestFailure("EthEscrowTimeoutRelease - 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("EthEscrowTimeoutRelease - FAIL: Couldn't load order from Alice")
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_FULFILLMENT":
            raise TestFailure("EthEscrowTimeoutRelease - FAIL: Alice failed to detect payment")
        if resp["funded"] == False:
            raise TestFailure("EthEscrowTimeoutRelease - 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("EthEscrowTimeoutRelease - FAIL: Fulfillment post endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure("EthEscrowTimeoutRelease - 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("EthEscrowTimeoutRelease - FAIL: Couldn't load order from Bob")
        resp = json.loads(r.text)
        if resp["state"] != "FULFILLED":
            raise TestFailure("EthEscrowTimeoutRelease - 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("EthEscrowTimeoutRelease - FAIL: Couldn't load order from Bob")
        resp = json.loads(r.text)
        if resp["state"] != "FULFILLED":
            raise TestFailure("EthEscrowTimeoutRelease - 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("EthEscrowTimeoutRelease - FAIL: Release escrow internal server error %s", resp["reason"])
        elif r.status_code != 401:
            raise TestFailure("EthEscrowTimeoutRelease - FAIL: Failed to raise error when releasing escrow before timeout")

        for i in range(6):
            time.sleep(900)

        # 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("EthEscrowTimeoutRelease - FAIL: Release escrow error %s", resp["reason"])

        time.sleep(20)

        time.sleep(2)

        # Check the funds moved into alice's wallet
        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 <= 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("EthEscrowTimeoutRelease - FAIL: Couldn't load order from Bob")
        resp = json.loads(r.text)
        if resp["state"] != "PAYMENT_FINALIZED":
            raise TestFailure("EthEscrowTimeoutRelease - 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("EthEscrowTimeoutRelease - FAIL: Couldn't load order from Bob")
        resp = json.loads(r.text)
        if resp["state"] != "PAYMENT_FINALIZED":
            raise TestFailure("EthEscrowTimeoutRelease - FAIL: Bob failed to set order to payment finalized")

        print("EthEscrowTimeoutRelease - PASS")
Beispiel #10
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("generatetoaddress", 1, address)
        time.sleep(2)
        self.send_bitcoin_cmd("generate", 125)
        time.sleep(3)

        # 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.post(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)

        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(10)

        # 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")
Beispiel #11
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(3)
        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(
                "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)
        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(
                "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"] + "ipns/" + alice[
            "peerId"] + "/listings.json"
        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
        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 = {
            "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"
        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")
    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/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(
                "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"] + "ob/listings/" + alice["peerId"]
        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/" + 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(
                "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(10)

        # 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(
                "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 = {
            "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(
                "PurchaseDirectOfflineTest - FAIL: Spend post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "PurchaseDirectOfflineTest - 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(
                "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(60)

        # 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/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(
                    "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: order confirmation 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/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 <= 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 payment2"
            )
        if resp["funded"] == False:
            raise TestFailure(
                "PurchaseDirectOnlineTest - FAIL: Alice incorrectly saved as unfunded"
            )

        print("PurchaseDirectOfflineTest - 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
        generated_coins = 10
        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("DisputeCloseSplitTest - FAIL: Address endpoint not found")
        else:
            raise TestFailure("DisputeCloseSplitTest - 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("DisputeCloseSplitTest - FAIL: Profile post endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure("DisputeCloseSplitTest - FAIL: Profile POST failed. Reason: %s", resp["reason"])
        time.sleep(4)

        # make charlie a moderator
        with open('testdata/'+ self.moderator_version +'/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("DisputeCloseSplitTest - FAIL: Moderator post endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure("DisputeCloseSplitTest - FAIL: Moderator POST failed. Reason: %s", resp["reason"])
        moderatorId = charlie["peerId"]
        time.sleep(4)

        # post profile for alice
        with open('testdata/'+ self.vendor_version +'/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/'+ self.vendor_version +'/listing.json') as listing_file:
            listing_json = json.load(listing_file, object_pairs_hook=OrderedDict)
        if self.vendor_version == "v4":
            listing_json["metadata"]["priceCurrency"] = "t" + self.cointype
        else:
            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("DisputeCloseSplitTest - FAIL: Listing post endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure("DisputeCloseSplitTest - 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("DisputeCloseSplitTest - FAIL: Couldn't get listing index")
        resp = json.loads(r.text)
        listingId = resp[0]["hash"]

        # bob send order
        with open('testdata/'+ self.buyer_version +'/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("DisputeCloseSplitTest - FAIL: Purchase post endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            self.print_logs(alice, "ob.log")
            raise TestFailure("DisputeCloseSplitTest - 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("DisputeCloseSplitTest - FAIL: Couldn't load order from Bob")
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_PAYMENT":
            raise TestFailure("DisputeCloseSplitTest - FAIL: Bob purchase saved in incorrect state")
        if resp["funded"] == True:
            raise TestFailure("DisputeCloseSplitTest - 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("DisputeCloseSplitTest - FAIL: Couldn't load order from Alice")
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_PAYMENT":
            raise TestFailure("DisputeCloseSplitTest - FAIL: Alice purchase saved in incorrect state")
        if resp["funded"] == True:
            raise TestFailure("DisputeCloseSplitTest - FAIL: Alice incorrectly saved as funded")

        # fund order
        spend = {
            "currencyCode": "T" + self.cointype,
            "address": payment_address,
            "amount": payment_amount["amount"],
            "feeLevel": "NORMAL",
            "requireAssociateOrder": False
        }
        if self.buyer_version == "v4":
            spend["amount"] = payment_amount
            spend["wallet"] = "T" + self.cointype

        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("DisputeCloseSplitTest - FAIL: Spend post endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure("DisputeCloseSplitTest - FAIL: Spend POST failed. Reason: %s", resp["reason"])
        time.sleep(30)

        # check bob detected payment
        api_url = bob["gateway_url"] + "ob/order/" + orderId
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure("DisputeCloseSplitTest - FAIL: Couldn't load order from Bob")
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_FULFILLMENT":
            raise TestFailure("DisputeCloseSplitTest - FAIL: Bob failed to detect his payment")
        if resp["funded"] == False:
            raise TestFailure("DisputeCloseSplitTest - 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("DisputeCloseSplitTest - FAIL: Couldn't load order from Alice")
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_FULFILLMENT":
            raise TestFailure("DisputeCloseSplitTest - FAIL: Alice failed to detect payment")
        if resp["funded"] == False:
            raise TestFailure("DisputeCloseSplitTest - 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("DisputeCloseSplitTest - FAIL: OpenDispute post endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure("DisputeCloseSplitTest - 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("DisputeCloseSplitTest - FAIL: Couldn't load order from Bob")
        resp = json.loads(r.text)
        if resp["state"] != "DISPUTED":
            raise TestFailure("DisputeCloseSplitTest - 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("DisputeCloseSplitTest - FAIL: Couldn't load order from Alice")
        resp = json.loads(r.text)
        if resp["state"] != "DISPUTED":
            raise TestFailure("DisputeCloseSplitTest - 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("DisputeCloseSplitTest - FAIL: Couldn't load case from Clarlie")
        resp = json.loads(r.text, object_pairs_hook=OrderedDict)
        if resp["state"] != "DISPUTED":
            raise TestFailure("DisputeCloseSplitTest - FAIL: Charlie failed to detect the dispute")

        # Charlie close dispute
        dispute_resolution = {
            "OrderID": orderId,
            "Resolution": "I'm siding with Bob",
            "BuyerPercentage": 50,
            "VendorPercentage": 50
        }
        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("DisputeCloseSplitTest - FAIL: CloseDispute post endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure("DisputeCloseSplitTest - 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("DisputeCloseSplitTest - FAIL: Couldn't load order from Alice")
        resp = json.loads(r.text)
        if resp["state"] != "DECIDED":
            self.print_logs(alice, "ob.log")
            raise TestFailure("DisputeCloseSplitTest - 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("DisputeCloseSplitTest - FAIL: Couldn't load order from Bob")
        resp = json.loads(r.text, object_pairs_hook=OrderedDict)
        if resp["state"] != "DECIDED":
            raise TestFailure("DisputeCloseSplitTest - 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("DisputeCloseSplitTest - FAIL: Couldn't load case from Clarlie")
        resp = json.loads(r.text, object_pairs_hook=OrderedDict)
        if resp["state"] != "RESOLVED":
            raise TestFailure("DisputeCloseSplitTest - 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("DisputeCloseSplitTest - FAIL: ReleaseFunds post endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure("DisputeCloseSplitTest - FAIL: ReleaseFunds POST failed. Reason: %s", resp["reason"])
        time.sleep(20)

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

        # 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"])
            amt = 0
            if self.buyer_version == "v4":
                amt = payment_amount
            else:
                amt = int(payment_amount["amount"])

            if confirmed + unconfirmed <= (generated_coins*100000000) - amt:
                raise TestFailure("DisputeCloseSplitTest - FAIL: Bob failed to detect dispute payout")
        elif r.status_code == 404:
            raise TestFailure("DisputeCloseSplitTest - FAIL: Receive coins endpoint not found")
        else:
            raise TestFailure("DisputeCloseSplitTest - FAIL: Unknown response")



        # Check alice received payout
        api_url = alice["gateway_url"] + "wallet/balance/T" + self.cointype
        time.sleep(20)
        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("DisputeCloseSplitTest - FAIL: Alice failed to detect dispute payout")
        elif r.status_code == 404:
            raise TestFailure("DisputeCloseSplitTest - FAIL: Receive coins endpoint not found")
        else:
            raise TestFailure("DisputeCloseSplitTest - 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("DisputeCloseSplitTest - FAIL: Couldn't load order from Bob")
        resp = json.loads(r.text, object_pairs_hook=OrderedDict)
        if len(resp["paymentAddressTransactions"]) != 2:
            raise TestFailure("DisputeCloseSplitTest - FAIL: Bob failed to record payout transaction")
        if resp["state"] != "RESOLVED":
            raise TestFailure("DisputeCloseSplitTest - 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("DisputeCloseSplitTest - FAIL: Couldn't load order from Alice")
        resp = json.loads(r.text, object_pairs_hook=OrderedDict)
        if len(resp["paymentAddressTransactions"]) != 2:
            raise TestFailure("DisputeCloseSplitTest - FAIL: Alice failed to record payout transaction")
        if resp["state"] != "RESOLVED":
            raise TestFailure("DisputeCloseSplitTest - FAIL: Alice failed to set state to RESOLVED")

        print("DisputeCloseSplitTest - 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("CompleteDirectOnlineTest - FAIL: Address endpoint not found")
        else:
            raise TestFailure("CompleteDirectOnlineTest - 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/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("CompleteDirectOnlineTest - FAIL: Listing post endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure("CompleteDirectOnlineTest - 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("CompleteDirectOnlineTest - 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("CompleteDirectOnlineTest - FAIL: Purchase post endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure("CompleteDirectOnlineTest - 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("CompleteDirectOnlineTest - FAIL: Couldn't load order from Bob")
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_PAYMENT":
            raise TestFailure("CompleteDirectOnlineTest - FAIL: Bob purchase saved in incorrect state")
        if resp["funded"] == True:
            raise TestFailure("CompleteDirectOnlineTest - 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("CompleteDirectOnlineTest - FAIL: Couldn't load order from Alice")
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_PAYMENT":
            raise TestFailure("CompleteDirectOnlineTest - FAIL: Alice purchase saved in incorrect state")
        if resp["funded"] == True:
            raise TestFailure("CompleteDirectOnlineTest - 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("CompleteDirectOnlineTest - FAIL: Spend post endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure("CompleteDirectOnlineTest - 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("CompleteDirectOnlineTest - FAIL: Couldn't load order from Bob")
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_FULFILLMENT":
            raise TestFailure("CompleteDirectOnlineTest - FAIL: Bob failed to detect his payment")
        if resp["funded"] == False:
            raise TestFailure("CompleteDirectOnlineTest - 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("CompleteDirectOnlineTest - FAIL: Couldn't load order from Alice")
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_FULFILLMENT":
            raise TestFailure("CompleteDirectOnlineTest - FAIL: Alice failed to detect payment")
        if resp["funded"] == False:
            raise TestFailure("CompleteDirectOnlineTest - 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("CompleteDirectOnlineTest - FAIL: Fulfillment post endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure("CompleteDirectOnlineTest - 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("CompleteDirectOnlineTest - FAIL: Couldn't load order from Bob")
        resp = json.loads(r.text)
        if resp["state"] != "FULFILLED":
            raise TestFailure("CompleteDirectOnlineTest - 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("CompleteDirectOnlineTest - FAIL: Couldn't load order from Bob")
        resp = json.loads(r.text)
        if resp["state"] != "FULFILLED":
            raise TestFailure("CompleteDirectOnlineTest - 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("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"] != "COMPLETED":
            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"] != "COMPLETED":
            raise TestFailure("CompleteDirectOnlineTest - FAIL: Bob failed to order completion")

        print("CompleteDirectOnlineTest - PASS")
Beispiel #15
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(
                "CompleteModeratedWithTimeout - FAIL: Address endpoint not found"
            )
        else:
            raise TestFailure(
                "CompleteModeratedWithTimeout - 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(
                "CompleteModeratedWithTimeout - FAIL: Profile post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "CompleteModeratedWithTimeout - FAIL: Profile POST failed. Reason: %s",
                resp["reason"])
        time.sleep(4)

        # make charlie a moderator
        with open('testdata/' + self.moderator_version +
                  '/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(
                "CompleteModeratedWithTimeout - FAIL: Moderator post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "CompleteModeratedWithTimeout - FAIL: Moderator POST failed. Reason: %s",
                resp["reason"])
        moderatorId = charlie["peerId"]
        time.sleep(4)

        # post profile for alice
        with open('testdata/' + self.vendor_version +
                  '/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/' + self.vendor_version +
                  '/listing.json') as listing_file:
            listing_json = json.load(listing_file,
                                     object_pairs_hook=OrderedDict)
        if self.vendor_version == "v4":
            listing_json["metadata"]["priceCurrency"] = "t" + self.cointype
        else:
            listing_json["item"]["priceCurrency"]["code"] = "t" + self.cointype
        listing_json["metadata"]["acceptedCurrencies"] = ["t" + self.cointype]
        slug = listing_json["slug"]
        listing_json["moderators"] = [moderatorId]
        listing_json["metadata"]["escrowTimeoutHours"] = 1000
        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(
                "CompleteModeratedWithTimeout - FAIL: Listing post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "CompleteModeratedWithTimeout - 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(
                "CompleteModeratedWithTimeout - FAIL: Couldn't get listing index"
            )
        resp = json.loads(r.text)
        listingId = resp[0]["hash"]

        # bob send order
        with open('testdata/' + self.buyer_version +
                  '/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(
                "CompleteModeratedWithTimeout - FAIL: Purchase post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            self.print_logs(alice, "ob.log")
            raise TestFailure(
                "CompleteModeratedWithTimeout - 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(
                "CompleteModeratedWithTimeout - FAIL: Couldn't load order from Bob"
            )
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_PAYMENT":
            raise TestFailure(
                "CompleteModeratedWithTimeout - FAIL: Bob purchase saved in incorrect state"
            )
        if resp["funded"] == True:
            raise TestFailure(
                "CompleteModeratedWithTimeout - 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(
                "CompleteModeratedWithTimeout - FAIL: Couldn't load order from Alice"
            )
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_PAYMENT":
            raise TestFailure(
                "CompleteModeratedWithTimeout - FAIL: Alice purchase saved in incorrect state"
            )
        if resp["funded"] == True:
            raise TestFailure(
                "CompleteModeratedWithTimeout - FAIL: Alice incorrectly saved as funded"
            )

        # fund order
        spend = {
            "currencyCode": "T" + self.cointype,
            "address": payment_address,
            "amount": payment_amount["amount"],
            "feeLevel": "NORMAL",
            "requireAssociateOrder": False
        }
        if self.buyer_version == "v4":
            spend["amount"] = payment_amount
            spend["wallet"] = "T" + self.cointype

        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(
                "CompleteModeratedWithTimeout - FAIL: Spend post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "CompleteModeratedWithTimeout - 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(
                "CompleteModeratedWithTimeout - FAIL: Couldn't load order from Bob"
            )
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_FULFILLMENT":
            raise TestFailure(
                "CompleteModeratedWithTimeout - FAIL: Bob failed to detect his payment"
            )
        if resp["funded"] == False:
            raise TestFailure(
                "CompleteModeratedWithTimeout - 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(
                "CompleteModeratedWithTimeout - FAIL: Couldn't load order from Alice"
            )
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_FULFILLMENT":
            raise TestFailure(
                "CompleteModeratedWithTimeout - FAIL: Alice failed to detect payment"
            )
        if resp["funded"] == False:
            raise TestFailure(
                "CompleteModeratedWithTimeout - FAIL: Alice incorrectly saved as unfunded"
            )

        # alice send order fulfillment
        with open('testdata/' + self.vendor_version +
                  '/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(
                "CompleteModeratedWithTimeout - FAIL: Fulfillment post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "CompleteModeratedWithTimeout - 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(
                "CompleteModeratedWithTimeout - FAIL: Couldn't load order from Bob"
            )
        resp = json.loads(r.text)
        if resp["state"] != "FULFILLED":
            raise TestFailure(
                "CompleteModeratedWithTimeout - 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(
                "CompleteModeratedWithTimeout - FAIL: Couldn't load order from Bob"
            )
        resp = json.loads(r.text)
        if resp["state"] != "FULFILLED":
            raise TestFailure(
                "CompleteModeratedWithTimeout - FAIL: Alice failed to order fulfillment"
            )

        # bob send order completion
        with open('testdata/' + self.buyer_version +
                  '/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(
                "CompleteModeratedWithTimeout - FAIL: Completion post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "CompleteModeratedWithTimeout - 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(
                "CompleteModeratedWithTimeout - FAIL: Couldn't load order from Alice"
            )
        resp = json.loads(r.text)
        if resp["state"] != "COMPLETED":
            raise TestFailure(
                "CompleteModeratedWithTimeout - 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(
                "CompleteModeratedWithTimeout - FAIL: Couldn't load order from Bob"
            )
        resp = json.loads(r.text)
        if resp["state"] != "COMPLETED":
            raise TestFailure(
                "CompleteModeratedWithTimeout - FAIL: Bob failed to order completion"
            )

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

        # Check the funds moved into alice's wallet
        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 <= 0:
                raise TestFailure(
                    "CompleteModeratedWithTimeout - FAIL: Alice failed to receive the multisig payout"
                )
        else:
            raise TestFailure(
                "CompleteModeratedWithTimeout - FAIL: Failed to query Alice's balance"
            )

        print("CompleteModeratedWithTimeout - 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["metadata"]["pricingCurrency"] = "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 = {
            "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("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: QmS73grfbWgWrNztd8Lns9GCG3jjRNDfcPYg2VYQzKDZSt
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 #17
0
    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.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"] != "AWAITING_PAYMENT":
            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["paymentAddressTransactions"]) <= 0:
            raise TestFailure("CancelDirectOfflineTest - FAIL: Bob failed to detect his payment")
        if resp["funded"] == False:
            raise TestFailure("CancelDirectOfflineTest - FAIL: Bob incorrectly saved as unfunded")
        if resp["state"] != "PENDING":
            raise TestFailure("CancelDirectOfflineTest - FAIL: Bob purchase saved in incorrect state")

        # 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 "refundAddressTransaction" not in resp or resp["refundAddressTransaction"] == {}:
            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:
            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 #18
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(
                "EthPurchaseDigital - FAIL: Address endpoint not found")
        else:
            raise TestFailure("EthPurchaseDigital - 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_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(
                "EthPurchaseDigital - FAIL: Listing post endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "EthPurchaseDigital - 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(
                "EthPurchaseDigital - 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"
        print("before purchase : ", api_url)
        print(json.dumps(order_json, indent=4))
        r = requests.post(api_url, data=json.dumps(order_json, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "EthPurchaseDigital - FAIL: Purchase post endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "EthPurchaseDigital - 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(
                "EthPurchaseDigital - FAIL: Couldn't load order from Bob")
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_PAYMENT":
            raise TestFailure(
                "EthPurchaseDigital - FAIL: Bob purchase saved in incorrect state"
            )
        if resp["funded"] == True:
            raise TestFailure(
                "EthPurchaseDigital - 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(
                "EthPurchaseDigital - FAIL: Couldn't load order from Alice")
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_PAYMENT":
            raise TestFailure(
                "EthPurchaseDigital - FAIL: Alice purchase saved in incorrect state"
            )
        if resp["funded"] == True:
            raise TestFailure(
                "EthPurchaseDigital - 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(
                "EthPurchaseDigital - FAIL: Spend post endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "EthPurchaseDigital - 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(
                "EthPurchaseDigital - FAIL: Couldn't load order from Bob")
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_FULFILLMENT":
            raise TestFailure(
                "EthPurchaseDigital - FAIL: Bob failed to detect his payment")
        if resp["funded"] == False:
            raise TestFailure(
                "EthPurchaseDigital - 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(
                "EthPurchaseDigital - FAIL: Couldn't load order from Alice")
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_FULFILLMENT":
            raise TestFailure(
                "EthPurchaseDigital - FAIL: Alice failed to detect payment")
        if resp["funded"] == False:
            raise TestFailure(
                "EthPurchaseDigital - FAIL: Alice incorrectly saved as unfunded"
            )

        print("EthPurchaseDigital - 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)
        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("PurchaseModeratedOfflineTest - FAIL: Address endpoint not found")
        else:
            raise TestFailure("PurchaseModeratedOfflineTest - FAIL: Unknown response")
        self.send_bitcoin_cmd("generatetoaddress", 1, address)
        time.sleep(2)
        self.send_bitcoin_cmd("generate", 125)
        time.sleep(3)

        # 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("PurchaseModeratedOfflineTest - FAIL: Listing post endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure("PurchaseModeratedOfflineTest - FAIL: Listing POST failed. Reason: %s", resp["reason"])
        time.sleep(4)

        # 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.post(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)

        # 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("PurchaseModeratedOfflineTest - 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
        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("PurchaseModeratedOfflineTest - FAIL: Purchase post endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure("PurchaseModeratedOfflineTest - 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("PurchaseModeratedOfflineTest - 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("PurchaseModeratedOfflineTest - FAIL: Couldn't load order from Bob")
        resp = json.loads(r.text)
        if resp["state"] != "PENDING":
            raise TestFailure("PurchaseModeratedOfflineTest - FAIL: Bob purchase saved in incorrect state")
        if resp["funded"] == True:
            raise TestFailure("PurchaseModeratedOfflineTest - 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("PurchaseModeratedOfflineTest - FAIL: Spend post endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure("PurchaseModeratedOfflineTest - FAIL: Purchase POST failed. Reason: %s", resp["reason"])
        time.sleep(5)

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

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

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

        # 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("PurchaseModeratedOfflineTest - FAIL: Couldn't load order from Alice")
        resp = json.loads(r.text)
        if resp["state"] != "PENDING":
            raise TestFailure("PurchaseModeratedOfflineTest - FAIL: Alice failed to detect payment")
        if resp["funded"] == False:
            raise TestFailure("PurchaseModeratedOfflineTest - 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("PurchaseModeratedOfflineTest - FAIL: Alice should have zero balance at this point")
        else:
            raise TestFailure("PurchaseModeratedOfflineTest - 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("PurchaseModeratedOfflineTest - FAIL: Order confirmation post endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure("PurchaseModeratedOfflineTest - 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"] != "FUNDED" and resp["state"] != "CONFIRMED":
            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"] != "FUNDED":
            raise TestFailure("PurchaseDirectOnlineTest - FAIL: Alice failed to detect payment")
        if resp["funded"] == False:
            raise TestFailure("PurchaseDirectOnlineTest - FAIL: Alice incorrectly saved as unfunded")

        print("PurchaseModeratedOfflineTest - PASS")
    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
        print("see the wallet address : ", api_url)
        r = requests.get(api_url)
        print("raw resp : ")
        print(r)
        if r.status_code == 200:
            print("resp : ", json.loads(r.text))
            resp = json.loads(r.text)
            address = resp["address"]
        elif r.status_code == 404:
            raise TestFailure(
                "EthPurchaseDirectOnlineTest - FAIL: Address endpoint not found"
            )
        else:
            raise TestFailure(
                "EthPurchaseDirectOnlineTest - FAIL: Unknown response")
        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/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 = vendor["gateway_url"] + "ob/listing"
        r = requests.post(api_url, data=json.dumps(listing_json, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "EthPurchaseDirectOnlineTest - FAIL: Listing post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "EthPurchaseDirectOnlineTest - FAIL: Listing POST failed. Reason: %s",
                resp["reason"])
        time.sleep(4)

        # get listing hash
        api_url = vendor["gateway_url"] + "ob/listings/" + vendor["peerId"]
        r = requests.get(api_url)
        if r.status_code != 200:
            raise TestFailure(
                "EthPurchaseDirectOnlineTest - 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(
                "EthPurchaseDirectOnlineTest - FAIL: Purchase post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "EthPurchaseDirectOnlineTest - 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(
                "EthPurchaseDirectOnlineTest - FAIL: Couldn't load order from Buyer"
            )
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_PAYMENT":
            raise TestFailure(
                "EthPurchaseDirectOnlineTest - FAIL: Buyer purchase saved in incorrect state"
            )
        if resp["funded"] == True:
            raise TestFailure(
                "EthPurchaseDirectOnlineTest - 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(
                "EthPurchaseDirectOnlineTest - FAIL: Couldn't load order from Vendor"
            )
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_PAYMENT":
            raise TestFailure(
                "EthPurchaseDirectOnlineTest - FAIL: Vendor purchase saved in incorrect state"
            )
        if resp["funded"] == True:
            raise TestFailure(
                "EthPurchaseDirectOnlineTest - FAIL: Vendor 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 = buyer["gateway_url"] + "ob/orderspend"
        print("orderspend spend ... ", api_url)
        print("payload : ", json.dumps(spend, indent=4))
        r = requests.post(api_url, data=json.dumps(spend, indent=4))
        if r.status_code == 404:
            raise TestFailure(
                "EthPurchaseDirectOnlineTest - FAIL: Spend post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "EthPurchaseDirectOnlineTest - 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(
                "EthPurchaseDirectOnlineTest - FAIL: Couldn't load order from Buyer"
            )
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_FULFILLMENT":
            raise TestFailure(
                "EthPurchaseDirectOnlineTest - FAIL: Buyer failed to detect his payment"
            )
        if resp["funded"] == False:
            raise TestFailure(
                "EthPurchaseDirectOnlineTest - 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(
                "EthPurchaseDirectOnlineTest - FAIL: Couldn't load order from Vendor"
            )
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_FULFILLMENT":
            raise TestFailure(
                "EthPurchaseDirectOnlineTest - FAIL: Vendor failed to detect payment"
            )
        if resp["funded"] == False:
            raise TestFailure(
                "EthPurchaseDirectOnlineTest - 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)
        print("after purchasing too much stuff, the response : ")
        print(r.status_code)
        print(resp)
        if r.status_code == 200:
            raise TestFailure(
                "EthPurchaseDirectOnlineTest - FAIL: Purchase POST should have failed failed."
            )
        if resp["reason"] != "not enough inventory":
            raise TestFailure(
                "EthPurchaseDirectOnlineTest - FAIL: Purchase POST failed with incorrect reason: %s",
                resp["reason"])
        if resp["code"] != "ERR_INSUFFICIENT_INVENTORY":
            raise TestFailure(
                "EthPurchaseDirectOnlineTest - FAIL: Purchase POST failed with incorrect code: %s",
                resp["code"])
        if resp["remainingInventory"] != '6':
            raise TestFailure(
                "EthPurchaseDirectOnlineTest - FAIL: Purchase POST failed with incorrect remainingInventory: %d",
                resp["remainingInventory"])

        print("EthPurchaseDirectOnlineTest - 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/" + 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("RefundDirectTest - FAIL: Address endpoint not found")
        else:
            raise TestFailure("RefundDirectTest - FAIL: Unknown response")
        self.send_bitcoin_cmd("sendtoaddress", address, 10)
        time.sleep(2)

        # generate some coins and send them to alice
        time.sleep(4)
        api_url = alice["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("RefundDirectTest - FAIL: Address endpoint not found")
        else:
            raise TestFailure("RefundDirectTest - 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/listing.json') as listing_file:
            listing_json = json.load(listing_file, object_pairs_hook=OrderedDict)
        listing_json["metadata"]["pricingCurrency"] = "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("RefundDirectTest - FAIL: Listing post endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure("RefundDirectTest - 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("RefundDirectTest - 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("RefundDirectTest - FAIL: Purchase post endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure("RefundDirectTest - 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("RefundDirectTest - FAIL: Couldn't load order from Bob")
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_PAYMENT":
            raise TestFailure("RefundDirectTest - FAIL: Bob purchase saved in incorrect state")
        if resp["funded"] == True:
            raise TestFailure("RefundDirectTest - 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("RefundDirectTest - FAIL: Couldn't load order from Alice")
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_PAYMENT":
            raise TestFailure("RefundDirectTest - FAIL: Alice purchase saved in incorrect state")
        if resp["funded"] == True:
            raise TestFailure("RefundDirectTest - 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("RefundDirectTest - FAIL: Spend post endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure("RefundDirectTest - 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("RefundDirectTest - FAIL: Couldn't load order from Bob")
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_FULFILLMENT":
            raise TestFailure("RefundDirectTest - FAIL: Bob failed to detect his payment")
        if resp["funded"] == False:
            raise TestFailure("RefundDirectTest - 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("RefundDirectTest - FAIL: Couldn't load order from Alice")
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_FULFILLMENT":
            raise TestFailure("RefundDirectTest - FAIL: Alice failed to detect payment")
        if resp["funded"] == False:
            raise TestFailure("RefundDirectTest - FAIL: Alice incorrectly saved as unfunded")

        # 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("RefundDirectTest - FAIL: Refund endpoint not found")
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure("RefundDirectTest - 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("RefundDirectTest - FAIL: Couldn't load order from Alice")
        resp = json.loads(r.text)
        if resp["state"] != "REFUNDED":
            raise TestFailure("RefundDirectTest - FAIL: Alice failed to save as rejected")
        if "refundAddressTransaction" not in resp:
            raise TestFailure("RefundDirectTest - FAIL: Alice failed to record 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("RefundDirectTest - FAIL: Couldn't load order from Bob")
        resp = json.loads(r.text)
        if resp["state"] != "REFUNDED":
            raise TestFailure("RefundDirectTest - FAIL: Bob failed to save as rejected")
        if "refundAddressTransaction" not in resp:
            raise TestFailure("RefundDirectTest - FAIL: Bob failed to record 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/" + 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("RefundDirectTest - FAIL: Bob failed to receive the multisig payout")
        else:
            raise TestFailure("RefundDirectTest - FAIL: Failed to query Bob's balance")

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

        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)
        ljson["metadata"]["pricingCurrency"] = "T" + self.cointype
        currency = "T" + self.cointype
        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 currency.lower() not in listing["acceptedCurrencies"]:
            raise TestFailure(
                "ListingsTest - FAIL: Listing should have acceptedCurrencies")

        # 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 currency.lower(
        ) not in resp["listing"]["metadata"]["acceptedCurrencies"]:
            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 currency.lower() not in resp[0]["acceptedCurrencies"]:
            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 currency.lower(
        ) not in resp["listing"]["metadata"]["acceptedCurrencies"]:
            raise TestFailure(
                "ListingsTest - FAIL: Listing should have acceptedCurrences in metadata"
            )

        print("ListingsTest - 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"
        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 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(
                "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"] + "ipns/" + alice[
            "peerId"] + "/listings/index.json"
        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
        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"] != "CONFIRMED":
            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"] != "CONFIRMED":
            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 = {
            "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"] != "FUNDED":
            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"] != "FUNDED":
            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)

        # Check alice received payout
        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(
                    "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["transactions"]) != 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["transactions"]) != 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]

        # 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/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("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/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("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/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("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/v5/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):
        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 #26
0
    def run_test(self):
        alice = self.nodes[1]
        bob = self.nodes[2]

        # initial bob 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(
                "EthCancelDirectOfflineTest - FAIL: Address endpoint not found"
            )
        else:
            raise TestFailure(
                "EthCancelDirectOfflineTest - 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))
        if r.status_code == 404:
            raise TestFailure(
                "EthCancelDirectOfflineTest - FAIL: Listing post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "EthCancelDirectOfflineTest - 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(
                "EthCancelDirectOfflineTest - 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["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(
                "EthCancelDirectOfflineTest - FAIL: Purchase post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "EthCancelDirectOfflineTest - 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(
                "EthCancelDirectOfflineTest - 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(
                "EthCancelDirectOfflineTest - FAIL: Couldn't load order from Bob"
            )
        resp = json.loads(r.text)
        if resp["state"] != "AWAITING_PAYMENT":
            raise TestFailure(
                "EthCancelDirectOfflineTest - FAIL: Bob purchase saved in incorrect state"
            )
        if resp["funded"] == True:
            raise TestFailure(
                "EthCancelDirectOfflineTest - 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(
                "EthCancelDirectOfflineTest - FAIL: Spend post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "EthCancelDirectOfflineTest - FAIL: Purchase POST failed. Reason: %s",
                resp["reason"])
        time.sleep(40)

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

        # 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(
                "EthCancelDirectOfflineTest - FAIL: Spend post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "EthCancelDirectOfflineTest - 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(
                "EthCancelDirectOfflineTest - FAIL: Couldn't load order from Bob"
            )
        resp = json.loads(r.text)
        if resp["state"] != "CANCELED":
            raise TestFailure(
                "EthCancelDirectOfflineTest - FAIL: Bob failed to save as canceled"
            )

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

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

        # 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"])
        else:
            raise TestFailure(
                "EthCancelDirectOfflineTest - FAIL: Failed to query Bob's balance"
            )

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

        # generate some coins and send them to buyer
        time.sleep(4)
        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(
                "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/' + self.vendor_version +
                  '/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/' + self.vendor_version +
                  '/listing_crypto.json') as listing_file:
            listing_json = json.load(listing_file,
                                     object_pairs_hook=OrderedDict)
            if self.vendor_version == "v5":
                listing_json["metadata"]["coinType"] = "TBCH"
                listing_json["metadata"]["coinDivisibility"] = 8
            listing_json["metadata"]["acceptedCurrencies"] = [
                "T" + self.cointype
            ]
            listing_json_with_modifier = deepcopy(listing_json)
            if self.vendor_version == "v4":
                listing_json_with_modifier["metadata"][
                    "priceModifier"] = self.price_modifier
            else:
                listing_json_with_modifier["item"][
                    "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 2 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:
                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:
                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/' + self.buyer_version +
                  '/order_crypto.json') as order_file:
            order_json = json.load(order_file, object_pairs_hook=OrderedDict)
        order_json["items"][0]["listingHash"] = listing_id
        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(
                "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 = int(resp["amount"]["amount"])

        with open('testdata/' + self.buyer_version +
                  '/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
        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(
                "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"]
        if self.buyer_version == "v4":
            payment_address_with_modifier = resp["amount"]
        else:
            payment_amount_with_modifier = int(resp["amount"]["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 #28
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/index.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"] != "CONFIRMED":
            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"] != "CONFIRMED":
            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"] != "FUNDED":
            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"] != "FUNDED":
            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(
                "CompleteDirectOnlineTest - FAIL: Fulfillment post endpoint not found"
            )
        elif r.status_code != 200:
            resp = json.loads(r.text)
            raise TestFailure(
                "CompleteDirectOnlineTest - 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(
                "CompleteDirectOnlineTest - FAIL: Couldn't load order from Bob"
            )
        resp = json.loads(r.text)
        if resp["state"] != "FULFILLED":
            raise TestFailure(
                "CompleteDirectOnlineTest - 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(
                "CompleteDirectOnlineTest - FAIL: Couldn't load order from Bob"
            )
        resp = json.loads(r.text)
        if resp["state"] != "FULFILLED":
            raise TestFailure(
                "CompleteDirectOnlineTest - 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(
                "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 fulfillment
        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 fulfillment 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"
            )

        # 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[1]
        buyer = self.nodes[2]

        # generate some coins and send them to buyer
        time.sleep(4)
        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("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)
        listing_json["metadata"]["acceptedCurrencies"] = ["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("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"] != "350000000000000000":
            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"] != "TETH":
            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
        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("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 int(payment_amount["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"] != "TETH":
            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"] != "TETH":
            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 = {
            "currencyCode": "T" + self.cointype,
            "address": payment_address,
            "amount": payment_amount["amount"],
            "feeLevel": "NORMAL",
            "requireAssociateOrder": False
        }
        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"] != "TETH":
            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
        time.sleep(20)
        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"] != "340000000000000000":
            raise TestFailure("PurchaseCryptoListingTest - FAIL: Inventory incorrect: %d", resp["ether"]["inventory"])

        print("PurchaseCryptoListingTest - 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))

        # 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")