def ajaxgateway(self, req, form):
        """
        """
        argd = wash_urlargd(
            form, {"projectid": (str, ""), "publicationid": (str, ""), "action": (str, ""), "current_field": (str, "")}
        )

        # Get parameters
        action = argd["action"]
        publicationid = argd["publicationid"]
        projectid = argd["projectid"]

        # Check if action is supported
        assert action in ("save", "verify_field", "submit", "unlinkproject", "linkproject")

        # JSON return dictionary
        out = {
            "errors": {},
            "warnings": {},
            "addclasses": {},
            "delclasses": {},
            "substitutions": {},
            "appends": {},
            "hiddens": [],
            "showns": [],
            "action": action,
        }

        if action == "verify_field":
            current_field = argd["current_field"]
            assert current_field
            metadata = wash_form(form, publicationid)
            out["errors"], out["warnings"] = OpenAIREPublication.static_check_metadata(
                metadata, publicationid, check_only_field=current_field, ln=argd["ln"]
            )
        else:
            user_info = collect_user_info(req)
            auth_code, auth_message = acc_authorize_action(user_info, "submit", doctype="OpenAIRE")
            assert auth_code == 0
            uid = user_info["uid"]
            publication = OpenAIREPublication(uid, publicationid, ln=argd["ln"])
            if action == "unlinkproject":
                publication.unlink_project(projectid)
                out["substitutions"]["#projectsbox_%s" % publicationid] = publication.get_projects_information()
                publication.check_projects()
                out["errors"], out["warnings"] = (
                    simple_metadata2namespaced_metadata(publication.errors, publicationid),
                    simple_metadata2namespaced_metadata(publication.warnings, publicationid),
                )
            elif action == "linkproject":
                publication.link_project(projectid)
                out["substitutions"]["#projectsbox_%s" % publicationid] = publication.get_projects_information()
                publication.check_projects()
                out["errors"], out["warnings"] = (
                    simple_metadata2namespaced_metadata(publication.errors, publicationid),
                    simple_metadata2namespaced_metadata(publication.warnings, publicationid),
                )
            else:
                publication.merge_form(form)
                publication.check_metadata()
                publication.check_projects()
                out["errors"], out["warnings"] = (
                    simple_metadata2namespaced_metadata(publication.errors, publicationid),
                    simple_metadata2namespaced_metadata(publication.warnings, publicationid),
                )
                if "".join(
                    out["errors"].values()
                ).strip():  # FIXME bad hack, we need a cleaner way to discover if there are errors
                    out["addclasses"]["#status_%s" % publicationid] = "error"
                    out["delclasses"]["#status_%s" % publicationid] = "warning ok empty"
                elif "".join(out["warnings"].values()).strip():
                    out["addclasses"]["#status_%s" % publicationid] = "warning"
                    out["delclasses"]["#status_%s" % publicationid] = "error ok empty"
                else:
                    out["addclasses"]["#status_%s" % publicationid] = "ok"
                    out["delclasses"]["#status_%s" % publicationid] = "warning error empty"

                if action == "save":
                    out["substitutions"][
                        "#publication_information_%s" % publicationid
                    ] = publication.get_publication_information()
                elif action == "submit":
                    if not "".join(out["errors"].values()).strip():
                        publication.upload_record()
                        out["appends"]["#submitted_publications"] = publication.get_publication_preview()
                        out["showns"].append("#submitted_publications")
                        out["hiddens"].append("#header_row_%s" % publicationid)
                        out["hiddens"].append("#body_row_%s" % publicationid)
        req.content_type = "application/json"
        return json.dumps(out)
class EngineTest(unittest.TestCase):
    user_id = None
    project_id = "283595"

    def record_marc_output(self, rec):
        """
        Print MARC for a given record.

        Used to compare a record generated by engine with the content of the record.
        """
        rec = rec.items()
        rec.sort()

        marc = ""

        for field_code, fields in rec:
            for subfields, ind1, ind2, a, b in fields:
                line = "\n%s%s%s " % (field_code, ind1 or "_", ind2 or "_")
                for subcode, subvalue in subfields:
                    line += "$$%s%s" % (subcode, subvalue)
                marc += line
        return marc

    def get_fixture(self, type):
        """ Retrieve fixutre and expected MARC """
        fixture = {}
        # Append pub id to field name.
        for field, val in FIXTURES[type].items():
            fixture["%s_%s" % (field, self.pub_id)] = val
        return fixture, MARC_FIXTURES[type]

    def assertMarcIsEqual(self, expected_marc, marc):
        """
        Assert that two MARC representations are equal, but exclude
        eg. 001 control fields.
        """
        # Filter out the control field.
        rm_pat = re.compile("^001.*$")
        rm_func = lambda x: not rm_pat.match(x)

        expected_marc_list = filter(rm_func, [x.strip() for x in expected_marc.split("\n")])
        marc_list = filter(rm_func, [x.strip() for x in marc.split("\n")])

        i = 0
        for i in range(0, max(len(expected_marc_list), len(marc_list))):
            try:
                l1 = expected_marc_list[i]
            except IndexError:
                l1 = ""
            try:
                l2 = marc_list[i]
            except IndexError:
                l2 = ""
            i += 1

            if l1.startswith("RE:"):
                if not re.match(l1[3:], l2):
                    raise AssertionError("%s doesn't match %s" % (l1, l2))
            else:
                if l1 != l2:
                    raise AssertionError("%s != %s" % (l1, l2))

    #
    # Tests
    #
    def setUp(self):
        if self.user_id == None:
            res = run_sql("SELECT id FROM user WHERE nickname='admin'")
            assert (len(res) == 1, "Couldn't find admin user")
            self.user_id = int(res[0][0])

        self.pub = OpenAIREPublication(self.user_id)
        self.pub_id = self.pub.publicationid

    def tearDown(self):
        self.pub.delete()
        self.pub = None
        self.pub_id = None

    def _test_pubtype(self, type):
        """
        Test MARC generated for a given publication type.
        """
        fixture, expected_marc = self.get_fixture(type)
        self.pub.merge_form(fixture)
        self.pub.check_metadata()
        self.pub.check_projects()
        self.pub.link_project(self.project_id)
        rec = self.pub.get_record()
        marc = self.record_marc_output(rec)

        self.assertMarcIsEqual(expected_marc, marc)

    def test_publishedArticle(self):
        self._test_pubtype("publishedArticle")

    def test_report(self):
        self._test_pubtype("report")

    def test_data(self):
        self._test_pubtype("data")

    def test_thesis(self):
        self._test_pubtype("thesis")

    def test_book(self):
        self._test_pubtype("book")

    def test_bookpart(self):
        self._test_pubtype("bookpart")

    def test_conference(self):
        self._test_pubtype("conferenceContribution")

    def test_preprint(self):
        self._test_pubtype("preprint")

    def test_workingpaper(self):
        self._test_pubtype("workingPaper")
    def ajaxgateway(self, req, form):
        """
        """
        argd = wash_urlargd(form, {'projectid': (str, ''), 'publicationid': (
            str, ''), 'action': (str, ''), 'current_field': (str, '')})

        # Get parameters
        action = argd['action']
        publicationid = argd['publicationid']
        projectid = argd['projectid']

        # Check if action is supported
        assert(action in (
            'save', 'verify_field', 'submit', 'unlinkproject', 'linkproject'))

        # JSON return dictionary
        out = {
            'errors': {},
            'warnings': {},
            'addclasses': {},
            'delclasses': {},
            'substitutions': {},
            'appends': {},
            'hiddens': [],
            'showns': [],
            'action': action,
        }

        if action == 'verify_field':
            current_field = argd['current_field']
            assert(current_field)
            metadata = wash_form(form, publicationid)
            out["errors"], out["warnings"] = OpenAIREPublication.static_check_metadata(metadata, publicationid, check_only_field=current_field, ln=argd['ln'])
        else:
            user_info = collect_user_info(req)
            auth_code, auth_message = acc_authorize_action(
                user_info, 'submit', doctype='OpenAIRE')
            assert(auth_code == 0)
            uid = user_info['uid']
            publication = OpenAIREPublication(
                uid, publicationid, ln=argd['ln'])
            if action == 'unlinkproject':
                publication.unlink_project(projectid)
                out["substitutions"]["#projectsbox_%s" %
                                     publicationid] = publication.get_projects_information()
                publication.check_projects()
                out["errors"], out["warnings"] = simple_metadata2namespaced_metadata(publication.errors, publicationid), simple_metadata2namespaced_metadata(publication.warnings, publicationid)
            elif action == 'linkproject':
                publication.link_project(projectid)
                out["substitutions"]["#projectsbox_%s" %
                                     publicationid] = publication.get_projects_information()
                publication.check_projects()
                out["errors"], out["warnings"] = simple_metadata2namespaced_metadata(publication.errors, publicationid), simple_metadata2namespaced_metadata(publication.warnings, publicationid)
            else:
                publication.merge_form(form)
                publication.check_metadata()
                publication.check_projects()
                out["errors"], out["warnings"] = simple_metadata2namespaced_metadata(publication.errors, publicationid), simple_metadata2namespaced_metadata(publication.warnings, publicationid)
                if "".join(out["errors"].values()).strip():  # FIXME bad hack, we need a cleaner way to discover if there are errors
                    out['addclasses']['#status_%s' % publicationid] = 'error'
                    out['delclasses']['#status_%s' %
                                      publicationid] = 'warning ok empty'
                elif "".join(out["warnings"].values()).strip():
                    out['addclasses']['#status_%s' % publicationid] = 'warning'
                    out['delclasses']['#status_%s' %
                                      publicationid] = 'error ok empty'
                else:
                    out['addclasses']['#status_%s' % publicationid] = 'ok'
                    out['delclasses']['#status_%s' %
                                      publicationid] = 'warning error empty'

                if action == 'save':
                    out["substitutions"]['#publication_information_%s' % publicationid] = publication.get_publication_information()
                elif action == 'submit':
                    if not "".join(out["errors"].values()).strip():
                        publication.upload_record()
                        out["appends"]['#submitted_publications'] = publication.get_publication_preview()
                        out["showns"].append('#submitted_publications')
                        out["hiddens"].append('#header_row_%s' % publicationid)
                        out["hiddens"].append('#body_row_%s' % publicationid)
        req.content_type = 'application/json'
        return json.dumps(out)
class EngineTest(unittest.TestCase):
    user_id = None
    project_id = '283595'


    def record_marc_output(self, rec):
        """
        Print MARC for a given record.

        Used to compare a record generated by engine with the content of the record.
        """
        rec = rec.items()
        rec.sort()

        marc = ""

        for field_code, fields in rec:
            for subfields, ind1, ind2, a, b in fields:
                line = "\n%s%s%s " % (field_code, ind1 or '_', ind2 or '_')
                for subcode, subvalue in subfields:
                    line += "$$%s%s" % (subcode, subvalue)
                marc += line
        return marc

    def get_fixture(self, type):
        """ Retrieve fixutre and expected MARC """
        fixture = {}
        # Append pub id to field name.
        for field, val in FIXTURES[type].items():
            fixture['%s_%s' % (field, self.pub_id)] = val
        return fixture, MARC_FIXTURES[type]

    def assertMarcIsEqual(self, expected_marc, marc):
        """
        Assert that two MARC representations are equal, but exclude
        eg. 001 control fields.
        """
        # Filter out the control field.
        rm_pat = re.compile("^001.*$")
        rm_func = lambda x: not rm_pat.match(x)

        expected_marc_list = filter(
            rm_func, [x.strip() for x in expected_marc.split('\n')])
        marc_list = filter(rm_func, [x.strip() for x in marc.split('\n')])

        i = 0
        for i in range(0, max(len(expected_marc_list), len(marc_list))):
            try:
                l1 = expected_marc_list[i]
            except IndexError:
                l1 = ''
            try:
                l2 = marc_list[i]
            except IndexError:
                l2 = ''
            i += 1

            if l1.startswith("RE:"):
                if not re.match(l1[3:], l2):
                    raise AssertionError("%s doesn't match %s" % (l1, l2))
            else:
                if l1 != l2:
                    raise AssertionError("%s != %s" % (l1, l2))

    #
    # Tests
    #
    def setUp(self):
        if self.user_id == None:
            res = run_sql("SELECT id FROM user WHERE nickname='admin'")
            assert(len(res) == 1, "Couldn't find admin user")
            self.user_id = int(res[0][0])

        self.pub = OpenAIREPublication(self.user_id)
        self.pub_id = self.pub.publicationid

    def tearDown(self):
        self.pub.delete()
        self.pub = None
        self.pub_id = None

    def _test_pubtype(self, type):
        """
        Test MARC generated for a given publication type.
        """
        fixture, expected_marc = self.get_fixture(type)
        self.pub.merge_form(fixture)
        self.pub.check_metadata()
        self.pub.check_projects()
        self.pub.link_project(self.project_id)
        rec = self.pub.get_record()
        marc = self.record_marc_output(rec)

        self.assertMarcIsEqual(expected_marc, marc)

    def test_publishedArticle(self):
        self._test_pubtype('publishedArticle')

    def test_report(self):
        self._test_pubtype('report')

    def test_data(self):
        self._test_pubtype('data')

    def test_thesis(self):
        self._test_pubtype('thesis')

    def test_book(self):
        self._test_pubtype('book')

    def test_bookpart(self):
        self._test_pubtype('bookpart')

    def test_conference(self):
        self._test_pubtype('conferenceContribution')

    def test_preprint(self):
        self._test_pubtype('preprint')

    def test_workingpaper(self):
        self._test_pubtype('workingPaper')
    def ajaxgateway(self, req, form):
        """
        """
        argd = wash_urlargd(
            form, {
                'projectid': (str, ''),
                'publicationid': (str, ''),
                'action': (str, ''),
                'current_field': (str, '')
            })

        # Get parameters
        action = argd['action']
        publicationid = argd['publicationid']
        projectid = argd['projectid']

        # Check if action is supported
        assert (action in ('save', 'verify_field', 'submit', 'unlinkproject',
                           'linkproject'))

        # JSON return dictionary
        out = {
            'errors': {},
            'warnings': {},
            'addclasses': {},
            'delclasses': {},
            'substitutions': {},
            'appends': {},
            'hiddens': [],
            'showns': [],
            'action': action,
        }

        if action == 'verify_field':
            current_field = argd['current_field']
            assert (current_field)
            metadata = wash_form(form, publicationid)
            out["errors"], out[
                "warnings"] = OpenAIREPublication.static_check_metadata(
                    metadata,
                    publicationid,
                    check_only_field=current_field,
                    ln=argd['ln'])
        else:
            user_info = collect_user_info(req)
            auth_code, auth_message = acc_authorize_action(user_info,
                                                           'submit',
                                                           doctype='OpenAIRE')
            assert (auth_code == 0)
            uid = user_info['uid']
            publication = OpenAIREPublication(uid,
                                              publicationid,
                                              ln=argd['ln'])
            if action == 'unlinkproject':
                publication.unlink_project(projectid)
                out["substitutions"][
                    "#projectsbox_%s" %
                    publicationid] = publication.get_projects_information()
                publication.check_projects()
                out["errors"], out[
                    "warnings"] = simple_metadata2namespaced_metadata(
                        publication.errors,
                        publicationid), simple_metadata2namespaced_metadata(
                            publication.warnings, publicationid)
            elif action == 'linkproject':
                publication.link_project(projectid)
                out["substitutions"][
                    "#projectsbox_%s" %
                    publicationid] = publication.get_projects_information()
                publication.check_projects()
                out["errors"], out[
                    "warnings"] = simple_metadata2namespaced_metadata(
                        publication.errors,
                        publicationid), simple_metadata2namespaced_metadata(
                            publication.warnings, publicationid)
            else:
                publication.merge_form(form)
                publication.check_metadata()
                publication.check_projects()
                out["errors"], out[
                    "warnings"] = simple_metadata2namespaced_metadata(
                        publication.errors,
                        publicationid), simple_metadata2namespaced_metadata(
                            publication.warnings, publicationid)
                if "".join(out["errors"].values()).strip(
                ):  # FIXME bad hack, we need a cleaner way to discover if there are errors
                    out['addclasses']['#status_%s' % publicationid] = 'error'
                    out['delclasses']['#status_%s' %
                                      publicationid] = 'warning ok empty'
                elif "".join(out["warnings"].values()).strip():
                    out['addclasses']['#status_%s' % publicationid] = 'warning'
                    out['delclasses']['#status_%s' %
                                      publicationid] = 'error ok empty'
                else:
                    out['addclasses']['#status_%s' % publicationid] = 'ok'
                    out['delclasses']['#status_%s' %
                                      publicationid] = 'warning error empty'

                if action == 'save':
                    out["substitutions"][
                        '#publication_information_%s' %
                        publicationid] = publication.get_publication_information(
                        )
                elif action == 'submit':
                    if not "".join(out["errors"].values()).strip():
                        publication.upload_record()
                        out["appends"][
                            '#submitted_publications'] = publication.get_publication_preview(
                            )
                        out["showns"].append('#submitted_publications')
                        out["hiddens"].append('#header_row_%s' % publicationid)
                        out["hiddens"].append('#body_row_%s' % publicationid)
        req.content_type = 'application/json'
        return json.dumps(out)