def screen_plates(self, user1):
        """Return Screen with Plates and an orphaned Plate."""
        # Create and name all the objects
        screen = ScreenI()
        screen.name = rstring('screen')

        for i in range(5):
            plate1 = PlateI()
            plate1.name = rstring('Plate%s' % i)
            screen.linkPlate(plate1)

        # Create single orphaned Plate
        plate = PlateI()
        plate.name = rstring('plate')

        screen = get_update_service(user1).saveAndReturnObject(screen)
        plate = get_update_service(user1).saveAndReturnObject(plate)

        # Add well to first plate
        plates = screen.linkedPlateList()
        plates.sort(key=lambda x: lower_or_none(unwrap(x.name)))
        plate_id = plates[0].id.val
        well = WellI()
        well.column = rint(0)
        well.row = rint(0)
        well.plate = PlateI(plate_id, False)
        image = self.create_test_image(
            size_x=5, size_y=5, session=user1[0].getSession())
        ws = WellSampleI()
        ws.image = ImageI(image.id, False)
        ws.well = well
        well.addWellSample(ws)
        well = get_update_service(user1).saveAndReturnObject(well)
        return screen, plate
    def test_pdi_parent_urls(self, user1, project_datasets):
        """Test browsing via urls in json /api/image -> project."""
        conn = get_connection(user1)
        user_name = conn.getUser().getName()
        client = self.new_django_client(user_name, user_name)
        version = api_settings.API_VERSIONS[-1]

        # Get image...
        project, dataset = project_datasets
        datasets = project.linkedDatasetList()
        datasets.sort(key=lambda x: lower_or_none(unwrap(x.name)))
        # ...from last dataset
        images = datasets[-1].linkedImageList()
        dataset_id = datasets[-1].id.val

        # Listing images - all have link to parents
        imgs_url = reverse('api_images', kwargs={'api_version': version})
        rsp = get_json(client, imgs_url, {'dataset': dataset_id})
        for i in rsp['data']:
            datasets_url = build_url(client, 'api_image_datasets',
                                     {'api_version': version,
                                      'image_id': i['@id']})
            assert i['url:datasets'] == datasets_url

        # Single Image has link to parents...
        img_url = imgs_url + '%s/' % images[0].id.val
        rsp = get_json(client, img_url)
        img_json = rsp['data']
        image_datasets_url = build_url(client, 'api_image_datasets',
                                       {'api_version': version,
                                        'image_id': images[0].id.val})
        assert img_json['url:datasets'] == image_datasets_url

        # List parent datasets
        rsp = get_json(client, image_datasets_url)
        assert_objects(conn, rsp['data'], [datasets[-1]], dtype='Dataset')

        # Listing Datasets (in Project) - all have link to parents
        datasets_url = reverse('api_datasets', kwargs={'api_version': version})
        rsp = get_json(client, datasets_url, {'project': project.id.val})
        for d in rsp['data']:
            projects_url = build_url(client, 'api_dataset_projects',
                                     {'api_version': version,
                                      'dataset_id': d['@id']})
            assert d['url:projects'] == projects_url

        # Single Dataset has link to parents...
        dataset_url = datasets_url + '%s/' % dataset_id
        rsp = get_json(client, dataset_url)
        dataset_json = rsp['data']
        dataset_projects_url = build_url(client, 'api_dataset_projects',
                                         {'api_version': version,
                                          'dataset_id': dataset_id})
        assert dataset_json['url:projects'] == dataset_projects_url

        # List parent Projects
        rsp = get_json(client, dataset_projects_url)
        assert_objects(conn, rsp['data'], [project])
 def user_screens(self, user1):
     """Create screens belonging to user1."""
     screens = []
     for i in range(5):
         screen = ScreenI()
         screen.name = rstring('Screen%s' % i)
         screens.append(screen)
     screens = get_update_service(user1).saveAndReturnArray(screens)
     screens.sort(key=lambda x: lower_or_none(unwrap(x.name)))
     return screens
    def test_spw_parent_urls(self, user1, screen_plates):
        """Test browsing via urls in json /api/image -> well, plate, screen."""
        conn = get_connection(user1)
        user_name = conn.getUser().getName()
        client = self.new_django_client(user_name, user_name)
        version = api_settings.API_VERSIONS[-1]
        screen, plate = screen_plates
        plates = screen.linkedPlateList()
        plates.sort(key=lambda x: lower_or_none(unwrap(x.name)))

        # Listing wells - all have link to parents
        wells_url = reverse('api_wells', kwargs={'api_version': version})
        rsp = get_json(client, wells_url)
        for w in rsp['data']:
            plates_url = build_url(client, 'api_well_plates',
                                   {'api_version': version,
                                    'well_id': w['@id']})
            assert w['url:plates'] == plates_url

        # Single Well has link to parents...
        well_id = rsp['data'][0]['@id']
        well_url = wells_url + '%s/' % well_id
        rsp = get_json(client, well_url)
        well_json = rsp['data']
        well_plates_url = build_url(client, 'api_well_plates',
                                    {'api_version': version,
                                     'well_id': well_id})
        assert well_json['url:plates'] == well_plates_url

        # Get parent plate (Plates list, filtered by Well)
        print('well_plates_url', well_plates_url)
        rsp = get_json(client, well_plates_url)
        plates_json = rsp['data']
        # check for link to Screen
        screens_url = build_url(client, 'api_plate_screens',
                                {'api_version': version,
                                 'plate_id': plates_json[0]['@id']})
        assert plates_json[0]['url:screens'] == screens_url
        plate_url = plates_json[0]['url:plate']
        assert_objects(conn, plates_json, [plates[0]], dtype='Plate')

        # Get the same Plate by ID
        rsp = get_json(client, plate_url)
        assert rsp['data']['url:screens'] == screens_url

        # Get Screen
        rsp = get_json(client, screens_url)
        assert_objects(conn, rsp['data'], [screen], dtype='Screen')
    def test_dataset_images(self, user1, dataset_images):
        """Test listing of Images in a Dataset."""
        conn = get_connection(user1)
        group_id = conn.getEventContext().groupId
        user_name = conn.getUser().getName()
        django_client = self.new_django_client(user_name, user_name)
        version = api_settings.API_VERSIONS[-1]

        dataset = dataset_images[0]
        images = dataset.linkedImageList()
        orphaned = dataset_images[1]

        images_url = reverse('api_images', kwargs={'api_version': version})
        datasets_url = reverse('api_datasets', kwargs={'api_version': version})

        # List ALL Images
        rsp = get_json(django_client, images_url, {'group': group_id})
        assert len(rsp['data']) == 6
        assert rsp['meta'] == {'totalCount': 6,
                               'limit': api_settings.API_LIMIT,
                               'maxLimit': api_settings.API_MAX_LIMIT,
                               'offset': 0}

        # Filter Images by Orphaned
        payload = {'orphaned': 'true', 'group': group_id}
        rsp = get_json(django_client, images_url, payload)
        assert_objects(conn, rsp['data'], [orphaned], dtype='Image',
                       group=group_id, opts={'load_pixels': True})
        assert rsp['meta'] == {'totalCount': 1,
                               'limit': api_settings.API_LIMIT,
                               'maxLimit': api_settings.API_MAX_LIMIT,
                               'offset': 0}

        # Filter Images by Dataset
        images.sort(key=lambda x: lower_or_none(unwrap(x.name)))
        payload = {'dataset': dataset.id.val}
        rsp = get_json(django_client, images_url, payload)
        # Manual check that Pixels & Type are loaded but Channels are not
        assert 'Type' in rsp['data'][0]['Pixels']
        assert 'Channels' not in rsp['data'][0]['Pixels']
        assert_objects(conn, rsp['data'], images, dtype='Image',
                       opts={'load_pixels': True})
        assert rsp['meta'] == {'totalCount': 5,
                               'limit': api_settings.API_LIMIT,
                               'maxLimit': api_settings.API_MAX_LIMIT,
                               'offset': 0}

        # Pagination, listing images via /datasets/:id/images/
        limit = 3
        dataset_images_url = datasets_url + "%s/images/" % dataset.id.val
        payload = {'dataset': dataset.id.val, 'limit': limit}
        rsp = get_json(django_client, dataset_images_url, payload)
        assert_objects(conn, rsp['data'], images[0:limit], dtype='Image',
                       opts={'load_pixels': True})
        assert rsp['meta'] == {'totalCount': 5,
                               'limit': limit,
                               'maxLimit': api_settings.API_MAX_LIMIT,
                               'offset': 0}
        payload['offset'] = limit   # page 2
        rsp = get_json(django_client, images_url, payload)
        assert_objects(conn, rsp['data'], images[limit:limit * 2],
                       dtype='Image', opts={'load_pixels': True})
        assert rsp['meta'] == {'totalCount': 5,
                               'limit': limit,
                               'maxLimit': api_settings.API_MAX_LIMIT,
                               'offset': limit}

        # Show ONLY the orphaned image (channels are loaded by default)
        img_url = images_url + '%s/' % orphaned.id.val
        rsp = get_json(django_client, img_url)
        # Manual check that Channels are loaded
        img_json = rsp['data']
        assert len(img_json['Pixels']['Channels']) == 1
        assert_objects(conn, [img_json], [orphaned], dtype='Image',
                       opts={'load_channels': True})
    def test_pdi_urls(self, user1, project_datasets):
        """Test browsing via urls in json /api/->PDI."""
        conn = get_connection(user1)
        user_name = conn.getUser().getName()
        client = self.new_django_client(user_name, user_name)
        version = api_settings.API_VERSIONS[-1]
        base_url = reverse('api_base', kwargs={'api_version': version})
        base_rsp = get_json(client, base_url)

        # List projects
        project, dataset = project_datasets
        projects_url = base_rsp['url:projects']
        rsp = get_json(client, projects_url)
        projects_json = rsp['data']
        extra = [{
            'url:project': build_url(client, 'api_project',
                                     {'api_version': version,
                                      'object_id': project.id.val}),
            'url:datasets': build_url(client, 'api_project_datasets',
                                      {'api_version': version,
                                       'project_id': project.id.val})
        }]
        assert_objects(conn, projects_json, [project], extra=extra)
        # View single Project
        rsp = get_json(client, projects_json[0]['url:project'])
        assert_objects(conn, [rsp['data']], [project],
                       extra=[{'url:datasets': extra[0]['url:datasets']}])

        # List datasets
        datasets_url = projects_json[0]['url:datasets']
        datasets = project.linkedDatasetList()
        datasets.sort(key=lambda x: lower_or_none(unwrap(x.name)))
        rsp = get_json(client, datasets_url)
        datasets_json = rsp['data']
        extra = []
        for d in datasets:
            extra.append({
                'url:dataset': build_url(client, 'api_dataset',
                                         {'api_version': version,
                                          'object_id': d.id.val}),
                'url:images': build_url(client, 'api_dataset_images',
                                        {'api_version': version,
                                         'dataset_id': d.id.val})
            })
        assert_objects(conn, datasets_json, datasets,
                       dtype='Dataset', extra=extra)
        # View single Dataset
        rsp = get_json(client, datasets_json[0]['url:dataset'])
        assert_objects(conn, [rsp['data']], datasets[0:1], dtype='Dataset',
                       extra=[{'url:images': extra[0]['url:images']}])

        # List images (from last Dataset)
        images_url = datasets_json[-1]['url:images']
        images = datasets[-1].linkedImageList()
        images.sort(key=lambda x: lower_or_none(unwrap(x.name)))
        rsp = get_json(client, images_url)
        images_json = rsp['data']
        extra = []
        for i in images:
            extra.append({
                'url:image': build_url(client, 'api_image',
                                       {'api_version': version,
                                        'object_id': i.id.val}),
            })
        assert_objects(conn, images_json, images,
                       dtype='Image', extra=extra, opts={'load_pixels': True})
        # View single Image
        rsp = get_json(client, images_json[0]['url:image'])
        assert_objects(conn, [rsp['data']], images[0:1], dtype='Image',
                       opts={'load_channels': True})
    def test_spw_urls(self, user1, screen_plates):
        """Test browsing via urls in json /api/->SPW."""
        conn = get_connection(user1)
        user_name = conn.getUser().getName()
        client = self.new_django_client(user_name, user_name)
        version = api_settings.API_VERSIONS[-1]
        base_url = reverse('api_base', kwargs={'api_version': version})
        base_rsp = get_json(client, base_url)

        # List screens
        screen, plate = screen_plates
        screens_url = base_rsp['url:screens']
        rsp = get_json(client, screens_url)
        screens_json = rsp['data']
        extra = [{
            'url:screen': build_url(client, 'api_screen',
                                    {'api_version': version,
                                     'object_id': screen.id.val}),
            'url:plates': build_url(client, 'api_screen_plates',
                                    {'api_version': version,
                                     'screen_id': screen.id.val})
        }]
        assert_objects(conn, screens_json, [screen], dtype='Screen',
                       extra=extra)
        # View single screen
        rsp = get_json(client, screens_json[0]['url:screen'])
        assert_objects(conn, [rsp['data']], [screen], dtype='Screen',
                       extra=[{'url:plates': extra[0]['url:plates']}])

        # List plates
        plates_url = screens_json[0]['url:plates']
        plates = screen.linkedPlateList()
        plates.sort(key=lambda x: lower_or_none(unwrap(x.name)))
        rsp = get_json(client, plates_url)
        plates_json = rsp['data']
        extra = []
        for p in plates:
            extra.append({
                'url:plate': build_url(client, 'api_plate',
                                       {'api_version': version,
                                        'object_id': p.id.val}),
                'url:wells': build_url(client, 'api_plate_wells',
                                       {'api_version': version,
                                        'plate_id': p.id.val})
            })
        assert_objects(conn, plates_json, plates, dtype='Plate', extra=extra)
        # View single plate
        rsp = get_json(client, plates_json[0]['url:plate'])
        plate_json = rsp['data']
        minMaxIndex = [0, 0]
        links = []
        for idx in range(minMaxIndex[0], minMaxIndex[1]+1):
            link = build_url(client, 'api_plate_wellsampleindex_wells',
                             {'api_version': version,
                              'plate_id': plate_json['@id'],
                              'index': idx})
            links.append(link)
        extra = [{'url:wellsampleindex_wells': links,
                  'omero:wellsampleIndex': minMaxIndex}]
        assert_objects(conn, [plate_json], plates[0:1], dtype='Plate',
                       extra=extra)

        # List wells of first plate
        wells_url = plates_json[0]['url:wells']
        rsp = get_json(client, wells_url)
        wells_json = rsp['data']
        well_id = wells_json[0]['@id']
        extra = [{'url:well': build_url(client, 'api_well',
                  {'api_version': version, 'object_id': well_id})}
                 ]
        assert_objects(conn, wells_json, [well_id], dtype='Well',
                       extra=extra, opts={'load_images': True}, client=client)
    def test_datasets_plates(self, user1, dtype, child_count,
                             project_datasets, screen_plates):
        """Test listing of Datasets in a Project and Plates in Screen."""
        conn = get_connection(user1)
        user_name = conn.getUser().getName()
        django_client = self.new_django_client(user_name, user_name)
        version = api_settings.API_VERSIONS[-1]

        # Handle parametrized dtype, setting up other variables
        if dtype == 'Dataset':
            parent = project_datasets[0]
            children = parent.linkedDatasetList()
            orphaned = project_datasets[1]
            url_name = 'api_datasets'
            ptype = 'project'
            # Counts of Images in Dataset / orphaned Dataset
            ds_or_pl_children = [{'omero:childCount': c} for c in range(5)]
            orph_ds_pl_children = [{'omero:childCount': 0}]
            pr_or_sc_children = [{'omero:childCount': 5}]

        else:
            parent = screen_plates[0]
            children = parent.linkedPlateList()
            orphaned = screen_plates[1]
            url_name = 'api_plates'
            ptype = 'screen'
            # Plates don't support childCount.
            ds_or_pl_children = None
            orph_ds_pl_children = None
            pr_or_sc_children = [{'omero:childCount': 5}]

        if not child_count:
            ds_or_pl_children = None
            orph_ds_pl_children = None
            pr_or_sc_children = None

        # Check child_count in Projects or Screens
        base_url = reverse('api_base', kwargs={'api_version': version})
        parents_url = "%sm/%ss/" % (base_url, ptype)
        payload = {'childCount': str(child_count).lower()}
        rsp = get_json(django_client, parents_url, payload)
        assert_objects(conn, rsp['data'], [parent], dtype=ptype,
                       extra=pr_or_sc_children)
        # And for single Project or Screen
        parent_url = "%sm/%ss/%s/" % (base_url, ptype, parent.id.val)
        rsp = get_json(django_client, parent_url, payload)
        assert_objects(conn, [rsp['data']], [parent], dtype=ptype,
                       extra=pr_or_sc_children)

        request_url = reverse(url_name, kwargs={'api_version': version})

        # List ALL Datasets or Plates
        rsp = get_json(django_client, request_url, payload)
        assert len(rsp['data']) == 6
        assert rsp['meta'] == {'totalCount': 6,
                               'limit': api_settings.API_LIMIT,
                               'maxLimit': api_settings.API_MAX_LIMIT,
                               'offset': 0}

        # Filter Datasets or Plates by Orphaned
        payload = {'orphaned': 'true', 'childCount': str(child_count).lower()}
        rsp = get_json(django_client, request_url, payload)
        assert_objects(conn, rsp['data'], [orphaned], dtype=dtype,
                       extra=orph_ds_pl_children)
        assert rsp['meta'] == {'totalCount': 1,
                               'limit': api_settings.API_LIMIT,
                               'maxLimit': api_settings.API_MAX_LIMIT,
                               'offset': 0}

        # Filter Datasets by Project or Plates by Screen
        children.sort(key=lambda x: lower_or_none(unwrap(x.name)))
        payload = {ptype: parent.id.val,
                   'childCount': str(child_count).lower()}
        rsp = get_json(django_client, request_url, payload)
        assert len(rsp['data']) == 5
        assert_objects(conn, rsp['data'], children, dtype=dtype,
                       extra=ds_or_pl_children)
        assert rsp['meta'] == {'totalCount': 5,
                               'limit': api_settings.API_LIMIT,
                               'maxLimit': api_settings.API_MAX_LIMIT,
                               'offset': 0}

        # Single (first) Dataset or Plate
        payload = {'childCount': str(child_count).lower()}
        object_url = "%sm/%ss/%s/" % (base_url, dtype.lower(),
                                      children[0].id.val)
        rsp = get_json(django_client, object_url, payload)
        if dtype == 'Plate':
            # When we get a single Plate, expect this (not when listing plates)
            ds_or_pl_children = [{'omero:wellsampleIndex': [0, 0]}]
        assert_objects(conn, [rsp['data']], [children[0]], dtype=dtype,
                       extra=ds_or_pl_children)

        # Pagination
        limit = 3
        payload = {ptype: parent.id.val,
                   'limit': limit,
                   'childCount': str(child_count).lower()}
        rsp = get_json(django_client, request_url, payload)
        extra = None
        if ds_or_pl_children is not None and len(ds_or_pl_children) > 1:
            extra = ds_or_pl_children[0:limit]
        assert_objects(conn, rsp['data'], children[0:limit], dtype=dtype,
                       extra=extra)
        assert rsp['meta'] == {'totalCount': 5,
                               'limit': limit,
                               'maxLimit': api_settings.API_MAX_LIMIT,
                               'offset': 0}
        payload['offset'] = limit   # page 2
        rsp = get_json(django_client, request_url, payload)
        if ds_or_pl_children is not None and len(ds_or_pl_children) > 1:
            extra = ds_or_pl_children[limit:limit * 2]
        assert_objects(conn, rsp['data'], children[limit:limit * 2],
                       dtype=dtype, extra=extra)
        assert rsp['meta'] == {'totalCount': 5,
                               'limit': limit,
                               'maxLimit': api_settings.API_MAX_LIMIT,
                               'offset': limit}
    def test_plate_index_wells(self, user1, multi_acquisition_plate):
        """
        Test filtering of Wells by Plate/PlateAcquisition AND index.

        Browse urls Plate -> PlateAcquisitions -> Wells
        OR Plate -> Wells (filtering by Index)
        """
        conn = get_connection(user1)
        user_name = conn.getUser().getName()
        client = self.new_django_client(user_name, user_name)
        version = api_settings.API_VERSIONS[-1]

        plate_id = multi_acquisition_plate.id.val
        plate_url = reverse('api_plate',
                            kwargs={'object_id': plate_id,
                                    'api_version': version})

        rsp = get_json(client, plate_url)
        plate_json = rsp['data']

        # Construct the urls we expect...
        plate_acq_link = build_url(client, 'api_plate_plateacquisitions',
                                   {'plate_id': plate_id,
                                    'api_version': version})
        well_link = build_url(client, 'api_plate_wells',
                              {'plate_id': plate_id,
                               'api_version': version})
        index_links = []
        plate = conn.getObject('Plate', plate_id)
        idx = plate.getNumberOfFields()
        for i in range(idx[0], idx[1]+1):
            link = build_url(client, 'api_plate_wellsampleindex_wells',
                             {'api_version': version,
                              'plate_id': plate_id,
                              'index': i})
            index_links.append(link)
        # ...and compare plate json:
        assert_objects(conn, [plate_json], [multi_acquisition_plate],
                       dtype='Plate',
                       extra=[{'url:plateacquisitions': plate_acq_link,
                               'url:wellsampleindex_wells': index_links,
                               'url:wells': well_link,
                               'omero:wellsampleIndex': list(idx)}])

        # Browse to /plate/:id/plateacquisitions/
        rsp = get_json(client, plate_acq_link)
        plate_acq_json = rsp['data']

        # Construct data & urls we expect...
        pas = list(plate.listPlateAcquisitions())
        pas.sort(key=lambda x: lower_or_none(unwrap(x.name)))
        paq_ids = [p.id for p in pas]
        extra = []
        for p, plate_acq in enumerate(pas):
            index_links = []
            for i in range(p * 3, (p + 1) * 3):
                link = build_url(client,
                                 'api_plateacquisition_wellsampleindex_wells',
                                 {'api_version': version,
                                  'plateacquisition_id': plate_acq.id,
                                  'index': i})
                index_links.append(link)
            extra.append({'url:wellsampleindex_wells': index_links,
                          'omero:wellsampleIndex': [p * 3, (p + 1) * 3 - 1]})
        # ...and compare
        assert_objects(conn, plate_acq_json, paq_ids,
                       dtype="PlateAcquisition",
                       extra=extra)