# Path: osf_tests/factories.py
# class SubjectFactory(DjangoModelFactory):
#     text = factory.Sequence(lambda n: 'Example Subject #{}'.format(n))
# 
#     class Meta:
#         model = models.Subject
# 
#     @classmethod
#     def _create(cls, target_class, parent=None, provider=None, bepress_subject=None, *args, **kwargs):
#         provider = provider or models.PreprintProvider.objects.first() or PreprintProviderFactory(_id='osf')
#         if provider._id != 'osf' and not bepress_subject:
#             osf = models.PreprintProvider.load('osf') or PreprintProviderFactory(_id='osf')
#             bepress_subject = SubjectFactory(provider=osf)
#         try:
#             ret = super()._create(target_class, parent=parent, provider=provider, bepress_subject=bepress_subject, *args, **kwargs)
#         except (IntegrityError, ValidationError):
#             ret = models.Subject.objects.get(text=kwargs['text'])
#             if parent:
#                 ret.parent = parent
#         return ret


import csv
import io
import pytest
import string
from nose.tools import assert_equal, assert_true
from rest_framework.exceptions import NotFound
from osf_tests.factories import SubjectFactory
from osf.models import RegistrationSchema, RegistrationProvider
from osf.registrations.utils import (BulkRegistrationUpload, InvalidHeadersError,
                                     FileUploadNotSupportedError, DuplicateHeadersError,
                                     get_excel_column_name, Store, CategoryField, LicenseField, ContributorField,
                                     MAX_EXCEL_COLUMN_NUMBER, METADATA_FIELDS)
    for key, value in expected_parsed.items():
        assert_true(key in parsed)
        actual = parsed[key]
        expected = value
        if actual and expected and type(actual) == list and type(expected) == list:
            if type(actual[0]) == str:
                assert_equal(actual.sort(), expected.sort(), msg=f'"{key}" parsed correctly')
                continue
        assert_equal(actual, expected)

def assert_errors(actual_errors, expected_errors):
    for error in actual_errors:
        assert_true('header' in error)
        assert_true('column_index' in error)
        assert_true('row_index' in error)
        assert_true('external_id' in error)
        assert_true(error['header'] in expected_errors)
        assert_equal(error['type'], expected_errors[error['header']])

    assert_true(len(actual_errors), len(expected_errors.keys()))

@pytest.mark.django_db
class TestBulkUploadParserValidationErrors:

    @pytest.fixture()
    def open_ended_schema(self):
        return RegistrationSchema.objects.get(name='Open-Ended Registration', schema_version=3)

    @pytest.fixture()
    def provider_subjects(self):

# Path: osf_tests/factories.py
# class SubjectFactory(DjangoModelFactory):
#     text = factory.Sequence(lambda n: 'Example Subject #{}'.format(n))
# 
#     class Meta:
#         model = models.Subject
# 
#     @classmethod
#     def _create(cls, target_class, parent=None, provider=None, bepress_subject=None, *args, **kwargs):
#         provider = provider or models.PreprintProvider.objects.first() or PreprintProviderFactory(_id='osf')
#         if provider._id != 'osf' and not bepress_subject:
#             osf = models.PreprintProvider.load('osf') or PreprintProviderFactory(_id='osf')
#             bepress_subject = SubjectFactory(provider=osf)
#         try:
#             ret = super()._create(target_class, parent=parent, provider=provider, bepress_subject=bepress_subject, *args, **kwargs)
#         except (IntegrityError, ValidationError):
#             ret = models.Subject.objects.get(text=kwargs['text'])
#             if parent:
#                 ret.parent = parent
#         return ret


# Path: osf_tests/test_registration_bulk_upload_parser.py
import csv
import io
import pytest
import string
from nose.tools import assert_equal, assert_true
from rest_framework.exceptions import NotFound
from osf_tests.factories import SubjectFactory
from osf.models import RegistrationSchema, RegistrationProvider
from osf.registrations.utils import (BulkRegistrationUpload, InvalidHeadersError,
                                     FileUploadNotSupportedError, DuplicateHeadersError,
                                     get_excel_column_name, Store, CategoryField, LicenseField, ContributorField,
                                     MAX_EXCEL_COLUMN_NUMBER, METADATA_FIELDS)

    for key, value in expected_parsed.items():
        assert_true(key in parsed)
        actual = parsed[key]
        expected = value
        if actual and expected and type(actual) == list and type(expected) == list:
            if type(actual[0]) == str:
                assert_equal(actual.sort(), expected.sort(), msg=f'"{key}" parsed correctly')
                continue
        assert_equal(actual, expected)

def assert_errors(actual_errors, expected_errors):
    for error in actual_errors:
        assert_true('header' in error)
        assert_true('column_index' in error)
        assert_true('row_index' in error)
        assert_true('external_id' in error)
        assert_true(error['header'] in expected_errors)
        assert_equal(error['type'], expected_errors[error['header']])

    assert_true(len(actual_errors), len(expected_errors.keys()))

@pytest.mark.django_db
class TestBulkUploadParserValidationErrors:

    @pytest.fixture()
    def open_ended_schema(self):
        return RegistrationSchema.objects.get(name='Open-Ended Registration', schema_version=3)

    @pytest.fixture()
    def provider_subjects(self):

        return [SubjectFactory() for _ in range(5)]