예제 #1
0
    def test_get_data_for_new_model_with_invalid_serialized_data(self):
        importer = Importer(models=["tests.Advert"])
        advert_serializer = importer.get_model_serializer(
            "tests.serializers.AdvertSerializer")

        mapped_fields = importer.convert_mapped_fields(
            self.get_invalid_record_fields(),
            self.get_invalid_mapped_fields(),
        )
        # Check serialized data is valid
        serialized_data = advert_serializer(data=mapped_fields)
        is_valid = serialized_data.is_valid()
        self.assertFalse(is_valid)

        data_for_new_model = importer.get_data_for_new_model(
            serialized_data, mapped_fields, 'recSomeRecordId')
        self.assertTrue(data_for_new_model.get('airtable_record_id'))
        self.assertEqual(data_for_new_model['airtable_record_id'],
                         'recSomeRecordId')
        self.assertIsNone(data_for_new_model.get('id'))
        self.assertIsNone(data_for_new_model.get('pk'))

        new_dict = mapped_fields.copy()
        new_dict['airtable_record_id'] = 'recSomeRecordId'
        self.assertDictEqual(data_for_new_model,
                             {'airtable_record_id': 'recSomeRecordId'})
예제 #2
0
 def test_update_object_with_invalid_serialized_data(self):
     instance = Advert.objects.first()
     importer = Importer(models=["tests.Advert"])
     advert_serializer = importer.get_model_serializer(
         "tests.serializers.AdvertSerializer")
     record_fields_dict = {
         "SEO Description": "Red is a scientifically proven...",
         "External Link": "https://example.com/",
         "slug": "red-its-new-blue",
         "Rating": "2.5",
     }
     mapped_fields_dict = {
         "SEO Description": "description",
         "External Link": "external_link",
         "slug": "slug",
         "Rating": "rating",
     }
     mapped_fields = importer.convert_mapped_fields(
         record_fields_dict,
         mapped_fields_dict,
     )
     serialized_data = advert_serializer(data=mapped_fields)
     is_valid = serialized_data.is_valid()
     self.assertFalse(is_valid)
     saved = importer.update_object(instance, 'recNewRecordId',
                                    serialized_data)
     self.assertTrue(saved)
예제 #3
0
    def test_get_or_set_cached_records(self):
        importer = Importer()
        self.assertEqual(importer.cached_records, {})

        # Make one API call. Update the cached_records.
        client1 = MockAirtable()
        all_records = importer.get_or_set_cached_records(client1)
        client1.get_all.assert_called()
        self.assertEqual(len(all_records), 4)

        cached_records = {client1.table_name: all_records}
        self.assertEqual(importer.cached_records, cached_records)
        self.assertEqual(len(importer.cached_records), 1)

        # Second API call is the same. Use the pre-existing cached records.
        client2 = MockAirtable()
        all_records = importer.get_or_set_cached_records(client2)
        self.assertEqual(importer.cached_records, cached_records)
        self.assertEqual(len(importer.cached_records), 1)

        # Third API call will create a new cached record in the cached_records dict
        client3 = MockAirtable()
        client3.table_name = "second_cached_entry"
        all_records = importer.get_or_set_cached_records(client3)
        self.assertNotEqual(importer.cached_records, cached_records)
        self.assertEqual(len(importer.cached_records), 2)
        # Ensure the internal dictionary "cache" has been updated
        cached_records["second_cached_entry"] = all_records
        self.assertEqual(importer.cached_records, cached_records)
예제 #4
0
 def test_get_incorrect_model_serializer(self):
     importer = Importer(models=["tests.Advert"])
     with self.assertRaises(AttributeError) as context:
         advert_serializer = importer.get_model_serializer(
             "tests.serializers.MissingSerializer")
     self.assertEqual(
         "module 'tests.serializers' has no attribute 'MissingSerializer'",
         str(context.exception))
예제 #5
0
    def test_update_object_by_uniq_col_name_missing_uniq_id(self):
        importer = Importer()
        updated = importer.update_object_by_uniq_col_name(
            field_mapping={'slug': ''},
            model=Advert,
            serialized_data=object,
            record_id='',
        )

        self.assertFalse(updated)
        self.assertEqual(importer.skipped, 1)
예제 #6
0
    def post(self, request, *args, **kwargs):
        form = AirtableImportModelForm(request.POST)
        if form.is_valid():
            model_label = form.cleaned_data["model"]
            importer = Importer(models=[model_label], options={"verbosity": 1})
            importer.run()
            message = f"{importer.created} items created. {importer.updated} items updated. {importer.skipped} items skipped."
            messages.add_message(request, messages.SUCCESS,
                                 f"Import succeeded with {message}")
        else:
            messages.add_message(request, messages.ERROR, "Could not import")

        return redirect(reverse("airtable_import_listing"))
예제 #7
0
    def test_get_model_settings(self):
        importer = Importer()
        # Finds config settings
        advert_settings = importer.get_model_settings(Advert)
        self.assertEqual(type(advert_settings), dict)
        self.assertDictEqual(settings.AIRTABLE_IMPORT_SETTINGS['tests.Advert'], advert_settings)

        # Does not find config settings
        unused_model_settings = importer.get_model_settings(ModelNotUsed)
        self.assertEqual(type(unused_model_settings), dict)
        self.assertDictEqual(unused_model_settings, {})

        # Finds adjacent model settings
        advert_settings = importer.get_model_settings(SimilarToAdvert)
        self.assertEqual(type(advert_settings), dict)
        self.assertDictEqual(settings.AIRTABLE_IMPORT_SETTINGS['tests.Advert'], advert_settings)
예제 #8
0
def import_models(models=None, verbosity=1):
    """
    Import models set in Wagtail Airtable settings

    Supports a list of models if only a limited set of models need to be imported.
    """

    # Avoid circular import error as get_validated_models is used in import_airtable
    # management command.
    from wagtail_airtable.management.commands.import_airtable import Importer

    models = get_validated_models(models=get_models_as_paths(models),
                                  as_path=True) if models else get_all_models(
                                      as_path=True)
    importer = Importer(models=models, options={"verbosity": verbosity})
    return importer.run()
예제 #9
0
 def test_get_column_to_field_names(self):
     importer = Importer()
     # The airtable column is the same name as the django field name
     # ie: slug and slug
     column, field = importer.get_column_to_field_names('slug')
     self.assertEqual(column, 'slug')
     self.assertEqual(field, 'slug')
     # The airtable column is different from the django field name
     # ie: "Page Title" and "title"
     column, field = importer.get_column_to_field_names({"Page Title": "title"})
     self.assertEqual(column, 'Page Title')
     self.assertEqual(field, 'title')
     # Different settings were specified and arent currently handled
     # Returns empty values
     column, field = importer.get_column_to_field_names(None)
     self.assertEqual(column, None)
     self.assertEqual(field, None)
예제 #10
0
    def test_update_object(self):
        importer = Importer(models=["tests.Advert"])
        advert_serializer = importer.get_model_serializer(
            "tests.serializers.AdvertSerializer")
        record_fields_dict = self.get_valid_record_fields()
        record_fields_dict[
            "SEO Description"] = "Red is a scientifically proven..."
        mapped_fields_dict = {
            "Page Title": "title",
            "SEO Description": "description",
            "External Link": "external_link",
            "Is Active": "is_active",
            "slug": "slug",
        }
        mapped_fields = importer.convert_mapped_fields(
            record_fields_dict,
            self.get_valid_mapped_fields(),
        )
        # Ensure mapped_fields are mapped properly
        self.assertEqual(
            mapped_fields['description'],
            "Red is a scientifically proven...",
        )
        # Check serialized data is valid
        serialized_data = advert_serializer(data=mapped_fields)
        is_valid = serialized_data.is_valid()
        self.assertTrue(is_valid)
        # Get the advert object.
        instance = Advert.objects.first()
        self.assertEqual(instance.airtable_record_id, '')
        # Importer should have zero updates objects.
        self.assertEqual(importer.updated, 0)

        saved = importer.update_object(instance, 'recNewRecordId',
                                       serialized_data)

        self.assertTrue(saved)
        # Check to make sure _skip_signals is set.
        self.assertTrue(instance._skip_signals)
        self.assertEqual(importer.updated, 1)
        self.assertEqual(importer.records_used, ['recNewRecordId'])
        # Re-fetch the Advert instance and check its airtable_record_id
        instance = Advert.objects.first()
        self.assertEqual(instance.airtable_record_id, 'recNewRecordId')
예제 #11
0
    def test_update_object_by_uniq_col_name_object_found(self):
        importer = Importer(models=["tests.Advert"])
        advert_serializer = importer.get_model_serializer(
            "tests.serializers.AdvertSerializer")
        record_fields_dict = {
            "Page Title": "Red! It's the new blue!",
            "SEO Description": "Red is a scientifically proven...",
            "External Link": "https://example.com/UPDATED",
            "Is Active": True,
            "rating": "1.5",
            "long_description":
            "<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Veniam laboriosam consequatur saepe. Repellat itaque dolores neque, impedit reprehenderit eum culpa voluptates harum sapiente nesciunt ratione.</p>",
            "points": 95,
            "slug": "red-its-new-blue",
        }
        mapped_fields_dict = {
            "Page Title": "title",
            "SEO Description": "description",
            "External Link": "external_link",
            "Is Active": "is_active",
            "slug": "slug",
        }
        mapped_fields = importer.convert_mapped_fields(
            record_fields_dict,
            mapped_fields_dict,
        )
        # Check serialized data is valid
        serialized_data = advert_serializer(data=mapped_fields)
        self.assertTrue(serialized_data.is_valid())

        # with self.assertRaises(AttributeError)
        updated = importer.update_object_by_uniq_col_name(
            field_mapping={'slug': 'red-its-new-blue'},
            model=Advert,
            serialized_data=serialized_data,
            record_id='recNewRecordId',
        )
        self.assertTrue(updated)
        self.assertEqual(importer.skipped, 0)
        self.assertEqual(importer.updated, 1)

        advert = Advert.objects.get(slug="red-its-new-blue")
        self.assertEqual(advert.external_link, "https://example.com/UPDATED")
예제 #12
0
 def test_convert_mapped_fields(self):
     importer = Importer()
     record_fields_dict = self.get_valid_record_fields()
     record_fields_dict['extra_field_from_airtable'] = "Not mapped"
     mapped_fields = importer.convert_mapped_fields(
         record_fields_dict,
         self.get_valid_mapped_fields(),
     )
     # Ensure the new mapped fields have the proper django field keys
     # And that each value is the value from the airtable record.
     self.assertEqual(
         mapped_fields['title'],
         "Red! It's the new blue!",
     )
     self.assertEqual(
         mapped_fields['description'],
         "Red is a scientifically proven...",
     )
     # Ensure a field from Airtable that's not mapped to a model does not get
     # passed into the newly mapped fields
     self.assertFalse(hasattr(mapped_fields, 'extra_field_from_airtable'))
예제 #13
0
    def test_debug_message(self):
        models = ["fake.ModelName"]
        text = "Testing debug message with high verbosity"

        importer = Importer(models=models, options=self.options)
        debug_message = importer.debug_message(text)
        self.assertEqual(debug_message, text)

        # Lower verbosity
        importer = Importer(models=models, options={'verbosity': 1})
        debug_message = importer.debug_message(text)
        self.assertEqual(debug_message, None)
예제 #14
0
 def test_get_model_serializer(self):
     importer = Importer(models=["tests.Advert"])
     advert_serializer = importer.get_model_serializer(
         "tests.serializers.AdvertSerializer")
     self.assertEqual(advert_serializer, AdvertSerializer)
예제 #15
0
 def test_is_wagtail_page(self):
     importer = Importer()
     self.assertTrue(importer.is_wagtail_page(SimplePage))
     self.assertFalse(importer.is_wagtail_page(Advert))