@ApiOperation(value = "Get all Widget types for specified Bundle (getBundleWidgetTypes)",
            notes = "Returns an array of Widget Type objects that belong to specified Widget Bundle." + WIDGET_TYPE_DESCRIPTION + " " + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH)
    @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
    @RequestMapping(value = "/widgetTypes", params = {"widgetsBundleId"}, method = RequestMethod.GET)
    @ResponseBody
    public List<WidgetType> getBundleWidgetTypes(
            @Parameter(description = "Widget Bundle Id", required = true)
            @RequestParam("widgetsBundleId") String strWidgetsBundleId) throws ThingsboardException {
        WidgetsBundleId widgetsBundleId = new WidgetsBundleId(toUUID(strWidgetsBundleId));
        return checkNotNull(widgetTypeService.findWidgetTypesByWidgetsBundleId(getTenantId(), widgetsBundleId));
    }
@Test
    public void testGetBundleWidgetTypes() throws Exception {
        WidgetsBundle widgetsBundle = new WidgetsBundle();
        widgetsBundle.setTitle("My widgets bundle");
        widgetsBundle = doPost("/api/widgetsBundle", widgetsBundle, WidgetsBundle.class);

        List<WidgetType> widgetTypes = new ArrayList<>();
        for (int i = 0; i < 89; i++) {
            WidgetTypeDetails widgetType = new WidgetTypeDetails();
            widgetType.setName("Widget Type " + i);
            widgetType.setDescriptor(JacksonUtil.fromString("{ \"someKey\": \"someValue\" }", JsonNode.class));
            widgetTypes.add(new WidgetType(doPost("/api/widgetType", widgetType, WidgetTypeDetails.class)));
        }

        List<String> widgetTypeIds = widgetTypes.stream().map(type -> type.getId().getId().toString()).collect(Collectors.toList());
        doPost("/api/widgetsBundle/" + widgetsBundle.getId().getId().toString() + "/widgetTypes", widgetTypeIds);

        List<WidgetType> loadedWidgetTypes = doGetTyped("/api/widgetTypes?widgetsBundleId={widgetsBundleId}",
                new TypeReference<>() {}, widgetsBundle.getId().getId().toString());

        Collections.sort(widgetTypes, idComparator);
        Collections.sort(loadedWidgetTypes, idComparator);

        Assert.assertEquals(widgetTypes, loadedWidgetTypes);

        loginCustomerUser();

        List<WidgetType> loadedWidgetTypesCustomer = doGetTyped("/api/widgetTypes?widgetsBundleId={widgetsBundleId}",
                new TypeReference<>() {}, widgetsBundle.getId().getId().toString());
        Collections.sort(loadedWidgetTypesCustomer, idComparator);
        Assert.assertEquals(widgetTypes, loadedWidgetTypesCustomer);

        List<WidgetTypeDetails> customerLoadedWidgetTypesDetails = doGetTyped("/api/widgetTypesDetails?widgetsBundleId={widgetsBundleId}",
                new TypeReference<>() {}, widgetsBundle.getId().getId().toString());
        List<WidgetType> widgetTypesFromDetailsListCustomer = customerLoadedWidgetTypesDetails.stream().map(WidgetType::new).collect(Collectors.toList());
        Collections.sort(widgetTypesFromDetailsListCustomer, idComparator);
        Assert.assertEquals(widgetTypesFromDetailsListCustomer, loadedWidgetTypes);

        loginSysAdmin();

        List<WidgetType> sysAdminLoadedWidgetTypes = doGetTyped("/api/widgetTypes?widgetsBundleId={widgetsBundleId}",
                new TypeReference<>() {}, widgetsBundle.getId().getId().toString());
        Collections.sort(sysAdminLoadedWidgetTypes, idComparator);
        Assert.assertEquals(widgetTypes, sysAdminLoadedWidgetTypes);

        List<WidgetTypeDetails> sysAdminLoadedWidgetTypesDetails = doGetTyped("/api/widgetTypesDetails?widgetsBundleId={widgetsBundleId}",
                new TypeReference<>() {}, widgetsBundle.getId().getId().toString());
        List<WidgetType> widgetTypesFromDetailsListSysAdmin = sysAdminLoadedWidgetTypesDetails.stream().map(WidgetType::new).collect(Collectors.toList());
        Collections.sort(widgetTypesFromDetailsListSysAdmin, idComparator);
        Assert.assertEquals(widgetTypesFromDetailsListSysAdmin, loadedWidgetTypes);
    }