Exemplo n.º 1
0
def embedded_signing(request):
    if request.method == 'POST':
        try:
            user_email = request.POST['email']
            user_name = request.POST['name']
            hsclient = HSClient(api_key=API_KEY)

            files = [os.path.dirname(os.path.realpath(__file__)) + "/docs/nda.pdf"]
            signers = [{"name": user_name, "email_address": user_email}]
            cc_email_addresses = []
            sr = hsclient.send_signature_request_embedded(
                "1", CLIENT_ID, files, [], "NDA with Acme Co.",
                "The NDA we talked about", "Please sign this NDA and then we" +
                " can discuss more. Let me know if you have any questions.",
                "", signers, cc_email_addresses)
            embedded = hsclient.get_embeded_object(sr.signatures[0]["signature_id"])
        except KeyError:
            return render(request, 'hellosign/embedded_signing.html', {
                'error_message': "Please enter both your name and email.",
            })
        except NoAuthMethod:
            return render(request, 'hellosign/embedded_signing.html', {
                'error_message': "Please update your settings to include a " +
                "value for API_KEY.",
            })
        else:
            return render(request, 'hellosign/embedded_signing.html', {
                    'client_id': CLIENT_ID,
                    'sign_url': str(embedded.sign_url)
                    })
    else:
        return render_to_response('hellosign/embedded_signing.html',
            context_instance=RequestContext(request))
Exemplo n.º 2
0
    def test_get_account_info(self):
        result = self.client.get_account_info()
        self.assertEquals(result, True)
        self.assertEquals(isinstance(self.client.account, Account), True)

        new_client = HSClient(api_key='non valid api key')
        result = new_client.get_account_info()
        self.assertEquals(result, False)
Exemplo n.º 3
0
    def test_get_account_info(self):
        result = self.client.get_account_info()
        self.assertEquals(result, True)
        self.assertEquals(isinstance(self.client.account, Account), True)

        new_client = HSClient(api_key='non valid api key')
        result = new_client.get_account_info()
        self.assertEquals(result, False)
Exemplo n.º 4
0
def embedded_template_requesting(request):
    try:
        hsclient = HSClient(api_key=API_KEY)
    except NoAuthMethod:
        return render(request, 'hellosign/embedded_template_requesting.html', {
            'error_message': "Please update your settings to include a " +
            "value for API_KEY.",
        })
    if request.method == 'POST':
        try:
            signers = []
            post_dict = parser.parse(request.POST.urlencode())
            template_id = post_dict["template"]
            for key, value in post_dict["signerRole"].iteritems():
                if value:
                    value['role_name'] = key
                    signers.append(value)
            ccs = []
            for key, value in post_dict["ccRole"].iteritems():
                # if value:
                ccs.append({'role_name': key, 'email_address': value})
            custom_fields = []
            for key, value in post_dict["cf"].iteritems():
                if value:
                    custom_fields.append({key: value})
            sr = hsclient.send_signature_request_embedded_with_rf(test_mode = "1",
                client_id = CLIENT_ID, reusable_form_id = template_id, title = "NDA with Acme Co.",
                subject = "The NDA we talked about", message = "Please sign this NDA and then we" +
                " can discuss more. Let me know if you have any questions.",
                signing_redirect_url = "", signers = signers, ccs = ccs, custom_fields = custom_fields)
            embedded = hsclient.get_embeded_object(sr.signatures[0]["signature_id"])
        # TODO: need some more validations here
        # except KeyError:
        #     return render(request, 'hellosign/embedded_template_requesting.html', {
        #         'error_message': "Please enter both your name and email.",
        #     })
        except NoAuthMethod:
            pass
        else:
            return render(request, 'hellosign/embedded_template_requesting.html', {
                    'client_id': CLIENT_ID,
                    'sign_url': str(embedded.sign_url)
                    })
    else:
        rf_list = hsclient.get_reusable_form_list()
        templates = "[";
        for rf in rf_list:
            # print json.dumps(rf.json_data)
            templates = templates + json.dumps(rf.json_data) + ", "
        templates = templates + "]"
        return render(request, 'hellosign/embedded_template_requesting.html', {
                    'templates': templates
                    })
Exemplo n.º 5
0
def oauth(request):
    try:
        oauth_accesstoken = request.session['access_token']
        oauth_token_type = request.session['token_type']
    except KeyError:
        oauth_accesstoken = None
        oauth_token_type = None

    if request.method == 'POST':
        try:
            user_email = request.POST['email']
            user_name = request.POST['name']

            user_hsclient = HSClient(api_accesstoken=request.session['oauth_accesstoken'], api_accesstokentype=request.session['oauth_token_type'])

            files = [os.path.dirname(os.path.realpath(__file__)) + "/docs/nda.pdf"]
            signers = [{"name": user_name, "email_address": user_email}]
            cc_email_addresses = []
            sr = user_hsclient.send_signature_request(
                "1", files, [], "OAuth Demo - NDA",
                "The NDA we talked about", "Please sign this NDA and then we" +
                " can discuss more. Let me know if you have any questions.",
                "", signers, cc_email_addresses)
        except KeyError:
            return render(request, 'hellosign/oauth.html', {
                'error_message': "Please enter both your name and email.",
                'client_id': CLIENT_ID
            })
        except NoAuthMethod:
            return render(request, 'hellosign/oauth.html', {
                'error_message': "Please update your settings to include a " +
                "value for API_KEY.",
                'client_id': CLIENT_ID
            })
        else:
            if isinstance(sr, SignatureRequest):
                return render(request, 'hellosign/oauth.html', {
                    'message': 'Request sent successfully.',
                    'oauth_accesstoken': request.session['oauth_accesstoken'],
                    'oauth_token_type': request.session['oauth_token_type'],
                    'client_id': CLIENT_ID
                    })
            else:
                return render(request, 'hellosign/oauth.html', {
                    'error_message': 'Unknow error',
                    'client_id': CLIENT_ID
                    })
    else:
        return render(request, 'hellosign/oauth.html', {
                'oauth_accesstoken': oauth_accesstoken,
                'oauth_token_type': oauth_token_type,
                'client_id': CLIENT_ID
            })
class TestReusableForm(TestCase):
    def setUp(self):
        self.client = HSClient(api_key=api_key)

    def test_resuable_form(self):
        # Get reusable form list, if there's any:
        # Add a user to our team, get the first one
        # if no team exist, create team
        # then add and remove a user from/to this reusableform
        # remove user from our team
        # destroy team
        rfl = self.client.get_reusable_form_list()
        self.assertTrue(isinstance(rfl, list))
        create_team = False
        if len(rfl) > 0:
            self.assertTrue(isinstance(rfl[0], ReusableForm))

            try:
                team = self.client.get_team_info()
            except NotFound:
                team = self.client.create_team("Team Name")
                self.assertTrue(isinstance(team, Team))
                self.assertEquals(team.name, "Team Name")
                create_team = True
            try:
                new_team = self.client.add_team_member("*****@*****.**")
                self.assertTrue(isinstance(new_team, Team))
                team = new_team
                # self.assertTrue("*****@*****.**" in [account["email_address"].encode('UTF8') for account in team.accounts])
            except Forbidden, e:
                pass
            rf = self.client.get_reusable_form(rfl[0].reusable_form_id)
            self.assertTrue(isinstance(rf, ReusableForm))

            try:
                rf = self.client.add_user_to_reusable_form(
                    rfl[0].reusable_form_id, None, "*****@*****.**")
                self.assertTrue(isinstance(rf, ReusableForm))

                rf = self.client.remove_user_from_reusable_form(
                    rfl[0].reusable_form_id, None, "*****@*****.**")
                self.assertTrue(isinstance(rf, ReusableForm))
            except Forbidden:
                pass
            new_team = self.client.remove_team_member("*****@*****.**")
            self.assertTrue(isinstance(team, Team))
            self.assertFalse("demo@example" in [
                account["email_address"].encode('UTF8')
                for account in team.accounts
            ])

            if create_team is True:
                result = self.client.destroy_team()
                self.assertTrue(result)
class TestReusableForm(TestCase):

    def setUp(self):
        self.client = HSClient(api_key=api_key)

    def test_resuable_form(self):
        # Get reusable form list, if there's any:
        # Add a user to our team, get the first one
        # if no team exist, create team
        # then add and remove a user from/to this reusableform
        # remove user from our team
        # destroy team
        rfl = self.client.get_reusable_form_list()
        self.assertTrue(isinstance(rfl, list))
        create_team = False
        if len(rfl) > 0:
            self.assertTrue(isinstance(rfl[0], ReusableForm))

            try:
                team = self.client.get_team_info()
            except NotFound:
                team = self.client.create_team("Team Name")
                self.assertTrue(isinstance(team, Team))
                self.assertEquals(team.name, "Team Name")
                create_team = True
            try:
                new_team = self.client.add_team_member("*****@*****.**")
                self.assertTrue(isinstance(new_team, Team))
                team = new_team
                # self.assertTrue("*****@*****.**" in [account["email_address"].encode('UTF8') for account in team.accounts])
            except Forbidden, e:
                pass
            rf = self.client.get_reusable_form(rfl[0].reusable_form_id)
            self.assertTrue(isinstance(rf, ReusableForm))

            try:
                rf = self.client.add_user_to_reusable_form(
                    rfl[0].reusable_form_id, None, "*****@*****.**")
                self.assertTrue(isinstance(rf, ReusableForm))

                rf = self.client.remove_user_from_reusable_form(
                    rfl[0].reusable_form_id, None, "*****@*****.**")
                self.assertTrue(isinstance(rf, ReusableForm))
            except Forbidden:
                pass
            new_team = self.client.remove_team_member("*****@*****.**")
            self.assertTrue(isinstance(team, Team))
            self.assertFalse("demo@example" in [account["email_address"].encode('UTF8') for account in team.accounts])

            if create_team is True:
                result = self.client.destroy_team()
                self.assertTrue(result)
Exemplo n.º 8
0
def oauth_callback(request):
    try:
        code = request.GET['code']
        state = request.GET['state']
        hsclient = HSClient(api_key=API_KEY)
        oauth = hsclient.get_oauth_data(code, CLIENT_ID, SECRET, state)
        request.session['oauth_accesstoken'] = oauth.access_token
        request.session['oauth_token_type'] = oauth.access_token_type
        # pdb.set_trace()

    except KeyError:
        return render(request, 'hellosign/oauth_callback.html', {
                'error_message': "No code or state found",
            })
    except BadRequest, e:
        # pdb.set_trace()
        return render(request, 'hellosign/oauth_callback.html', {
                'error_message': str(e),
            })
Exemplo n.º 9
0
def embedded_requesting(request):
    if request.method == 'POST':
        try:
            user_email = request.POST['user_email']
            user_name = request.POST['user_name']
            signer_name = request.POST['signer_name']
            signer_email = request.POST['signer_email']
            subject = request.POST['subject']
            message = request.POST['message']
            hsclient = HSClient(api_key=API_KEY)

            files = []
            form = UploadFileForm(request.POST, request.FILES)
            if form.is_valid():
                files.append(handle_uploaded_file(request.FILES['upload_file']))
            signers = [{"name": signer_name, "email_address": signer_email}]
            cc_email_addresses = []

            sr = hsclient.create_unclaimed_draft(
                "1", CLIENT_ID, '1', user_email, files, [], "request_signature",
                "The NDA we talked about", "Please sign this NDA and then we" +
                " can discuss more. Let me know if you have any questions.",
                signers, cc_email_addresses)
            sign_url = sr.claim_url
        # except KeyError:
        #     return render(request, 'hellosign/embedded_requesting.html', {
        #         'error_message': "Please enter both your name and email.",
        #     })

        except NoAuthMethod:
            return render(request, 'hellosign/embedded_requesting.html', {
                'error_message': "Please update your settings to include a " +
                "value for API_KEY.",
            })
        else:
            return render(request, 'hellosign/embedded_requesting.html', {
                    'client_id': CLIENT_ID,
                    'sign_url': str(sign_url)
                    })
    else:
        return render_to_response('hellosign/embedded_requesting.html',
            context_instance=RequestContext(request))
Exemplo n.º 10
0
class TestAccount(TestCase):

    def setUp(self):
        self.client = HSClient(api_key=api_key)

    def test_get_account_info(self):
        result = self.client.get_account_info()
        self.assertEquals(result, True)
        self.assertEquals(isinstance(self.client.account, Account), True)

        new_client = HSClient(api_key='non valid api key')
        result = new_client.get_account_info()
        self.assertEquals(result, False)

    def test_update_account_info(self):
        # We update nothing, but the api returns an Account object, so it is
        # considered successful
        result = self.client.get_account_info()
        self.assertEquals(result, True)
        result = self.client.update_account_info()
        self.assertEquals(result, True)

        self.client.account.callback_url = 'not valid url'
        account = self.client.update_account_info()
        self.assertEquals(account, False)

    def test_create_account_with_invalid_info(self):
        try:
            self.client.create_account("not valid [email protected]",
                                       "password")
        except BadRequest:
            pass
        try:
            self.client.create_account("", "password")
        except BadRequest:
            pass
        try:
            self.client.create_account("*****@*****.**", "")
        except BadRequest:
            pass
Exemplo n.º 11
0
class TestAccount(TestCase):
    def setUp(self):
        self.client = HSClient(api_key=api_key)

    def test_get_account_info(self):
        result = self.client.get_account_info()
        self.assertEquals(result, True)
        self.assertEquals(isinstance(self.client.account, Account), True)

        new_client = HSClient(api_key='non valid api key')
        result = new_client.get_account_info()
        self.assertEquals(result, False)

    def test_update_account_info(self):
        # We update nothing, but the api returns an Account object, so it is
        # considered successful
        result = self.client.get_account_info()
        self.assertEquals(result, True)
        result = self.client.update_account_info()
        self.assertEquals(result, True)

        self.client.account.callback_url = 'not valid url'
        account = self.client.update_account_info()
        self.assertEquals(account, False)

    def test_create_account_with_invalid_info(self):
        try:
            self.client.create_account("not valid [email protected]",
                                       "password")
        except BadRequest:
            pass
        try:
            self.client.create_account("", "password")
        except BadRequest:
            pass
        try:
            self.client.create_account("*****@*****.**", "")
        except BadRequest:
            pass
Exemplo n.º 12
0
class TestUnclaimedDraft(TestCase):
    def setUp(self):
        self.client = HSClient(api_key=api_key)

    def test_unclaimed_draft(self):

        files = [os.path.dirname(os.path.realpath(__file__)) + "/docs/nda.pdf"]
        signers = [{
            "name": "Signer Name",
            "email_address": "*****@*****.**"
        }]
        cc_email_addresses = ["*****@*****.**"]

        unclaimeddraft = self.client.create_unclaimed_draft(
            "1", client_id, "1", "*****@*****.**", files, [],
            UnclaimedDraft.UNCLAIMED_DRAFT_REQUEST_SIGNATURE_TYPE,
            "Test unclaimed draft", "Please do not reply to the messages",
            signers, cc_email_addresses)
        self.assertEquals(isinstance(unclaimeddraft, UnclaimedDraft), True)
class TestUnclaimedDraft(TestCase):

    def setUp(self):
        self.client = HSClient(api_key=api_key)

    def test_unclaimed_draft(self):

        files = [os.path.dirname(os.path.realpath(__file__)) + "/docs/nda.pdf"]
        signers = [{"name": "Signer Name",
                    "email_address": "*****@*****.**"}]
        cc_email_addresses = ["*****@*****.**"]

        unclaimeddraft = self.client.create_unclaimed_draft(
            "1", client_id, "1", "*****@*****.**",
            files, [],
            UnclaimedDraft.UNCLAIMED_DRAFT_REQUEST_SIGNATURE_TYPE,
            "Test unclaimed draft", "Please do not reply to the messages",
            signers, cc_email_addresses)
        self.assertEquals(isinstance(unclaimeddraft, UnclaimedDraft), True)
 def setUp(self):
     self.client = HSClient(api_key=api_key)
class TestSignatureRequest(TestCase):
    def setUp(self):
        self.client = HSClient(api_key=api_key)

    def test_signature_request_get(self):
        srl = self.client.get_signature_request_list()
        self.assertTrue(isinstance(srl, list))
        if len(srl) > 0:
            self.assertTrue(isinstance(srl[0], SignatureRequest))
            sr = self.client.get_signature_request(srl[0].signature_request_id)
            self.assertTrue(isinstance(sr, SignatureRequest))
            # Remind
            signer = srl[0].signatures[0].signer_email_address
            try:
                new_sr = self.client.remind_signature_request(srl[0].signature_request_id, signer)
                self.assertEquals(isinstance(new_sr, SignatureRequest), True)
            except Forbidden:
                pass
            # Download
            f = tempfile.NamedTemporaryFile(delete=True)
            temp_filename = f.name
            f.close()
            result = self.client.get_signature_request_file(srl[0].signature_request_id, temp_filename)
            self.assertTrue(result)

            result = self.client.get_signature_request_final_copy(srl[0].signature_request_id, temp_filename)
            self.assertTrue(result)

    def test_signature_request_send(self):
        files = [os.path.dirname(os.path.realpath(__file__)) + "/docs/nda.pdf"]
        signers = [{"name": "Signer Name", "email_address": "*****@*****.**"}]
        cc_email_addresses = ["*****@*****.**", "*****@*****.**"]

        sr = self.client.send_signature_request(
            "1",
            files,
            [],
            "A test signature request",
            "Test request",
            "This is a demo message",
            "",
            signers,
            cc_email_addresses,
        )
        self.assertEquals(isinstance(sr, SignatureRequest), True)
        self.assertEquals(sr.title, "A test signature request")
        self.assertEquals(sr.subject, "Test request")
        self.assertEquals(sr.message, "This is a demo message")

        try:
            self.client.send_signature_request(
                "1",
                None,
                [],
                "Test create signature request",
                "Ky giay no",
                "Ky vao giay no di, le di",
                "",
                signers,
                cc_email_addresses,
            )  # Error
        except HSException:
            pass
        result = self.client.cancel_signature_request(sr.signature_request_id)
        self.assertTrue(result)

        # create embedded
        sr = self.client.send_signature_request_embedded(
            "1",
            client_id,
            files,
            [],
            "A test signature request",
            "Test request",
            "This is a demo message",
            "",
            signers,
            cc_email_addresses,
        )

        self.assertEquals(isinstance(sr, SignatureRequest), True)
        self.assertEquals(sr.title, "A test signature request")
        self.assertEquals(sr.subject, "Test request")
        self.assertEquals(sr.message, "This is a demo message")

        result = self.client.cancel_signature_request(sr.signature_request_id)
        self.assertTrue(result)
Exemplo n.º 16
0
class TestTeam(TestCase):
    def setUp(self):
        self.client = HSClient(api_key=api_key)

    def test_add_team_member_with_invalid_info(self):
        try:
            self.client.add_team_member(email_address="in valid email")
        except BadRequest:
            pass

        try:
            self.client.add_team_member(account_id="in valid account_id")
        except NotFound:
            pass

    def test_team_functions(self):
        try:
            # You already in a team
            # save your old team name -> update new team name -> add member ->
            # remove member -> restore your old team name
            team = self.client.get_team_info()
            old_team_name = team.name

            try:
                result = self.client.destroy_team()
                self.assertTrue(result)
            except NotFound:
                pass

            team = self.client.create_team(old_team_name)
            self.assertEquals(team.name, old_team_name)

            team = self.client.update_team_name("New team name")
            self.assertEquals(isinstance(team, Team), True)

            try:
                team = self.client.add_team_member(
                    email_address="*****@*****.**")
                self.assertEquals(isinstance(team, Team), True)
            except Forbidden:
                pass
            try:
                self.client.add_team_member()
            except HSException:
                pass

            team = self.client.remove_team_member(
                email_address="*****@*****.**")
            self.assertEquals(isinstance(team, Team), True)

            team = self.client.update_team_name(old_team_name)
            self.assertEquals(isinstance(team, Team), True)
        except NotFound:
            # You do not belong to any teams
            # create team -> add member, remove member, destroy team
            team = self.client.create_team("New team")
            self.assertEquals(team.name, "New team")

            team = self.client.add_team_member(
                email_address="*****@*****.**")
            self.assertEquals(isinstance(team, Team), True)

            team = self.client.remove_team_member(
                email_address="*****@*****.**")
            self.assertEquals(isinstance(team, Team), True)

            result = self.client.destroy_team()
            self.assertEquals(result, True)
class TestSignatureRequest(TestCase):
    def setUp(self):
        self.client = HSClient(api_key=api_key)

    def test_signature_request_get(self):
        srl = self.client.get_signature_request_list()
        self.assertTrue(isinstance(srl, list))
        if len(srl) > 0:
            self.assertTrue(isinstance(srl[0], SignatureRequest))
            sr = self.client.get_signature_request(srl[0].signature_request_id)
            self.assertTrue(isinstance(sr, SignatureRequest))
            # Remind
            signer = srl[0].signatures[0].signer_email_address
            try:
                new_sr = self.client.remind_signature_request(
                    srl[0].signature_request_id, signer)
                self.assertEquals(isinstance(new_sr, SignatureRequest), True)
            except Forbidden:
                pass
            # Download
            f = tempfile.NamedTemporaryFile(delete=True)
            temp_filename = f.name
            f.close()
            result = self.client.get_signature_request_file(
                srl[0].signature_request_id, temp_filename)
            self.assertTrue(result)

            result = self.client.get_signature_request_final_copy(
                srl[0].signature_request_id, temp_filename)
            self.assertTrue(result)

    def test_signature_request_send(self):
        files = [os.path.dirname(os.path.realpath(__file__)) + "/docs/nda.pdf"]
        signers = [{
            "name": "Signer Name",
            "email_address": "*****@*****.**"
        }]
        cc_email_addresses = ["*****@*****.**", "*****@*****.**"]

        sr = self.client.send_signature_request("1", files, [],
                                                "A test signature request",
                                                "Test request",
                                                "This is a demo message", "",
                                                signers, cc_email_addresses)
        self.assertEquals(isinstance(sr, SignatureRequest), True)
        self.assertEquals(sr.title, "A test signature request")
        self.assertEquals(sr.subject, "Test request")
        self.assertEquals(sr.message, "This is a demo message")

        try:
            self.client.send_signature_request("1", None, [],
                                               "Test create signature request",
                                               "Ky giay no",
                                               "Ky vao giay no di, le di", "",
                                               signers,
                                               cc_email_addresses)  # Error
        except HSException:
            pass
        result = self.client.cancel_signature_request(sr.signature_request_id)
        self.assertTrue(result)

        # create embedded
        sr = self.client.send_signature_request_embedded(
            "1", client_id, files, [], "A test signature request",
            "Test request", "This is a demo message", "", signers,
            cc_email_addresses)

        self.assertEquals(isinstance(sr, SignatureRequest), True)
        self.assertEquals(sr.title, "A test signature request")
        self.assertEquals(sr.subject, "Test request")
        self.assertEquals(sr.message, "This is a demo message")

        result = self.client.cancel_signature_request(sr.signature_request_id)
        self.assertTrue(result)
Exemplo n.º 18
0
 def setUp(self):
     self.client = HSClient(api_key=api_key)
Exemplo n.º 19
0
class TestTeam(TestCase):

    def setUp(self):
        self.client = HSClient(api_key=api_key)

    def test_add_team_member_with_invalid_info(self):
        try:
            self.client.add_team_member(email_address="in valid email")
        except BadRequest:
            pass

        try:
            self.client.add_team_member(account_id="in valid account_id")
        except NotFound:
            pass

    def test_team_functions(self):
        try:
            # You already in a team
            # save your old team name -> update new team name -> add member ->
            # remove member -> restore your old team name
            team = self.client.get_team_info()
            old_team_name = team.name

            try:
                result = self.client.destroy_team()
                self.assertTrue(result)
            except NotFound:
                pass

            team = self.client.create_team(old_team_name)
            self.assertEquals(team.name, old_team_name)

            team = self.client.update_team_name("New team name")
            self.assertEquals(isinstance(team, Team), True)

            try:
                team = self.client.add_team_member(
                    email_address="*****@*****.**")
                self.assertEquals(isinstance(team, Team), True)
            except Forbidden:
                    pass
            try:
                self.client.add_team_member()
            except HSException:
                pass

            team = self.client.remove_team_member(
                email_address="*****@*****.**")
            self.assertEquals(isinstance(team, Team), True)

            team = self.client.update_team_name(old_team_name)
            self.assertEquals(isinstance(team, Team), True)
        except NotFound:
            # You do not belong to any teams
            # create team -> add member, remove member, destroy team
            team = self.client.create_team("New team")
            self.assertEquals(team.name, "New team")

            team = self.client.add_team_member(
                email_address="*****@*****.**")
            self.assertEquals(isinstance(team, Team), True)

            team = self.client.remove_team_member(
                email_address="*****@*****.**")
            self.assertEquals(isinstance(team, Team), True)

            result = self.client.destroy_team()
            self.assertEquals(result, True)