Example #1
0
    def test_import_projects(self):
        """Import a set of new projects, stacks and stack groups. This tests
        only the actual import. Retrieving the data to import from different
        sources is not part of this test.
        """
        project_url = 'https://catmaid-test/'
        data_folder = '/tmp/catmaid-test/'
        existing_projects = list(Project.objects.all())
        existing_project_ids = [p.id for p in existing_projects]

        p1_config = {
            'project': {
                'title': 'test-no-stacks',
            }
        }

        p2_config = {
            'project': {
                'title':
                'test-two-stacks',
                'stacks': [
                    {
                        # A basic stack, only with required information
                        'title':
                        'test-stack-1',
                        'dimension':
                        '(7, 17, 23)',
                        'resolution':
                        '(2, 3, 5)',
                        'zoomlevels':
                        -1,
                        'mirrors': [{
                            'title': 'test-mirror-1',
                            'fileextension': 'jpg'
                        }]
                    },
                    {
                        # A basic stack with a little more information
                        'title':
                        'test-stack-2',
                        'dimension':
                        '(7, 17, 23)',
                        'resolution':
                        '(2, 3, 5)',
                        'zoomlevels':
                        -1,
                        'mirrors': [{
                            'title': 'test-mirror-2',
                            'fileextension': 'jpg',
                            'url': 'https://this.is.my.stack/'
                        }]
                    },
                    {
                        # A stack with all optional properties
                        'title':
                        'test-stack-3',
                        'dimension':
                        '(4, 34, 9)',
                        'resolution':
                        '(1, 2, 3)',
                        'metadata':
                        'Test meta data',
                        'zoomlevels':
                        -1,
                        'translation':
                        '(10, 20, 30)',
                        'mirrors': [{
                            'title': 'test-mirror-3',
                            'folder': 'abc/',
                            'fileextension': 'jpg',
                            'tile_width': 123,
                            'tile_height': 456,
                            'tile_source_type': 2,
                        }],
                        'stackgroups': [{
                            # Add a single stack group with only this stack
                            # in it.
                            'title': 'Test group 1',
                            'relation': 'view',
                        }],
                    }
                ]
            }
        }

        pre_projects = [
            importer.PreProject(p1_config, project_url, data_folder),
            importer.PreProject(p2_config, project_url, data_folder),
        ]

        tags = []
        permissions = []
        default_tile_width = 256
        default_tile_height = 512
        default_tile_source_type = 5
        default_position = 0
        cls_graph_ids_to_link = []
        remove_unref_stack_data = False

        imported, not_imported = importer.import_projects(
            self.user, pre_projects, tags, permissions, default_tile_width,
            default_tile_height, default_tile_source_type,
            cls_graph_ids_to_link, remove_unref_stack_data)

        self.assertListEqual(pre_projects, imported)
        self.assertListEqual([], not_imported)

        new_projects = list(
            Project.objects.exclude(
                id__in=existing_project_ids).order_by('title'))
        self.assertEqual(2, len(new_projects))

        # Projects should be ordered by name, so the first project will be based
        # on p1_config. Test p1 first, it is not expected to have any stacks.
        p1 = new_projects[0]
        self.assertEqual(p1_config['project']['title'], p1.title)
        self.assertEqual(0, p1.stacks.all().count())

        # Test p2.
        p2 = new_projects[1]
        self.assertEqual(p2_config['project']['title'], p2.title)
        p2_stacks = p2.stacks.all().order_by('title')
        self.assertEqual(3, len(p2_stacks))
        p2cfg_stacks = p2_config['project']['stacks']
        for n, p2s in enumerate(p2_stacks):
            stack = p2cfg_stacks[n]

            # Test required fields
            self.assertEqual(stack['title'], p2s.title)
            six.assertCountEqual(self, literal_eval(stack['dimension']),
                                 literal_eval(str(p2s.dimension)))
            six.assertCountEqual(self, literal_eval(stack['resolution']),
                                 literal_eval(str(p2s.resolution)))
            self.assertEqual(stack['zoomlevels'], p2s.num_zoom_levels)

            # Test mirrors
            mirrors = p2s.stackmirror_set.all().order_by('title')
            self.assertEqual(len(stack['mirrors']), len(mirrors))
            for m, omirror in enumerate(mirrors):
                mirror = stack['mirrors'][m]

                self.assertEqual(mirror['title'], omirror.title)
                self.assertEqual(mirror['fileextension'],
                                 omirror.file_extension)

                # Test fields with potential default values
                self.assertEqual(mirror.get('position', default_position),
                                 omirror.position)
                self.assertEqual(mirror.get('tile_width', default_tile_width),
                                 omirror.tile_width)
                self.assertEqual(
                    mirror.get('tile_height', default_tile_height),
                    omirror.tile_height)
                self.assertEqual(
                    mirror.get('tile_source_type', default_tile_source_type),
                    omirror.tile_source_type)

                if 'url' in mirror:
                    image_base = mirror['url']
                else:
                    image_base = urljoin(
                        project_url,
                        urljoin(mirror.get('path', ''),
                                mirror.get('folder', '')))

                self.assertEqual(image_base, omirror.image_base)

            # Test project-stack link
            ps = ProjectStack.objects.get(project=p2.id, stack=p2s)
            six.assertCountEqual(
                self, literal_eval(stack.get('translation', '(0,0,0)')),
                literal_eval(str(ps.translation)))

            # Test stack groups
            ostack_group_links = StackStackGroup.objects.filter(
                stack=p2s).order_by('stack__title')
            stack_groups = stack.get('stackgroups', [])
            self.assertEqual(len(ostack_group_links), len(stack_groups))
            for m, sg_cfg in enumerate(stack_groups):
                ostack_group_link = ostack_group_links[m]
                ostack_group = ostack_group_link.stack_group
                self.assertEqual(sg_cfg['title'], ostack_group.title)
                self.assertEqual(sg_cfg['relation'],
                                 ostack_group_link.group_relation.name)
                self.assertEqual(sg_cfg.get('position', default_position),
                                 ostack_group_link.position)
Example #2
0
    def test_import_export_projects(self):
        """Export all projects, stacks and stack groups (without class instance
        and tracing data). Make then sure, they match the fixture.
        """

        p1_config = {
            'project': {
                'title': 'test-no-stacks',
                'stacks': tuple(),
            }
        }

        p2_config = {
            'project': {
                'title':
                'test-two-stacks',
                'stacks': [{
                    'broken_sections': [],
                    'title':
                    'test-stack-1',
                    'dimension':
                    '(7,17,23)',
                    'resolution':
                    '(2,3,5)',
                    'zoomlevels':
                    -1,
                    'orientation':
                    0,
                    'translation':
                    '(0,0,0)',
                    'metadata':
                    '',
                    'comment':
                    'Test comment',
                    'attribution':
                    'Test attribution',
                    'description':
                    'Simple test data',
                    'canary_location':
                    '(0,0,0)',
                    'placeholder_color':
                    '(0,0,0,1)',
                    'mirrors': [{
                        'title': 'test-mirror-1',
                        'url': 'https://catmaid-test/',
                        'tile_height': 512,
                        'tile_width': 256,
                        'fileextension': 'jpg',
                        'tile_source_type': 5,
                        'position': 2
                    }]
                }, {
                    'broken_sections': [],
                    'comment':
                    None,
                    'title':
                    'test-stack-2',
                    'dimension':
                    '(7,17,23)',
                    'metadata':
                    '',
                    'resolution':
                    '(2,3,5)',
                    'zoomlevels':
                    -1,
                    'orientation':
                    0,
                    'translation':
                    '(0,0,0)',
                    'attribution':
                    None,
                    'description':
                    '',
                    'canary_location':
                    '(0,0,0)',
                    'placeholder_color':
                    '(0.5,0.4,0.3,1)',
                    'mirrors': [{
                        'title': 'test-mirror-2',
                        'position': 0,
                        'url': 'https://this.is.my.stack/',
                        'tile_height': 400,
                        'tile_width': 300,
                        'fileextension': 'jpg',
                        'tile_source_type': 5,
                    }]
                }, {
                    'broken_sections': [],
                    'comment':
                    None,
                    'title':
                    'test-stack-3',
                    'dimension':
                    '(4,34,9)',
                    'metadata':
                    'Test meta data',
                    'resolution':
                    '(1,2,3)',
                    'zoomlevels':
                    -1,
                    'orientation':
                    0,
                    'translation':
                    '(0,0,0)',
                    'attribution':
                    None,
                    'description':
                    '',
                    'canary_location':
                    '(1,2,3)',
                    'placeholder_color':
                    '(0,0,0.3,0.1)',
                    'mirrors': [{
                        'title': 'test-mirror-3',
                        'position': 0,
                        'url': 'https://catmaid-test/abc/',
                        'tile_height': 456,
                        'tile_width': 123,
                        'fileextension': 'jpg',
                        'tile_source_type': 2,
                    }],
                    'stackgroups': [{
                        'relation': 'view',
                        'title': u'Test group 1'
                    }],
                }]
            }
        }

        project_url = 'https://catmaid-test/'
        data_folder = '/tmp/catmaid-test/'
        pre_projects = [
            importer.PreProject(p1_config, project_url, data_folder),
            importer.PreProject(p2_config, project_url, data_folder),
        ]
        config = [p1_config, p2_config]

        tags = []
        permissions = []
        default_tile_width = 256
        default_tile_height = 512
        default_tile_source_type = 1
        cls_graph_ids_to_link = []
        remove_unref_stack_data = False

        # Make sure there are no existing projects or stacks
        Project.objects.all().delete()
        Stack.objects.all().delete()

        imported, not_imported = importer.import_projects(
            self.user, pre_projects, tags, permissions, default_tile_width,
            default_tile_height, default_tile_source_type,
            cls_graph_ids_to_link, remove_unref_stack_data)

        self.assertEqual(0, len(not_imported))
        self.assertEqual(len(config), len(imported))

        # Make sure we can see all projects
        for p in Project.objects.all():
            assign_perm('can_browse', self.user, p)

        # Export imported data
        self.fake_authentication()
        response = self.client.get('/projects/export')
        self.assertEqual(response.status_code, 200)
        result = yaml.load(response.content.decode('utf-8'))

        def strip_ids(d):
            """ Recursively, strip all 'id' fields of dictionaries.
            """
            if type(d) == dict:
                if 'id' in d:
                    d.pop('id')
                for _, v in d.items():
                    strip_ids(v)
            if type(d) == list:
                for v in d:
                    strip_ids(v)

        # Results come with IDs, which we don't have in our input data. Strip
        # them to be able to simply compare dictionaries.
        strip_ids(result)

        for cp, p in zip(config, result):
            self.assertDictEqual(cp, p)