Merge "Show vendor products on vendor page"
This commit is contained in:
commit
ee8b6c0dd8
21
refstack-ui/app/components/vendors/vendor.html
vendored
21
refstack-ui/app/components/vendors/vendor.html
vendored
@ -80,6 +80,27 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<hr />
|
<hr />
|
||||||
|
<h3>Vendor Products</h3>
|
||||||
|
<table ng-show="ctrl.vendorProducts" class="table table-striped table-hover">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Product Type</th>
|
||||||
|
<th>Description</th>
|
||||||
|
<th>Visibility</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
|
||||||
|
<tbody>
|
||||||
|
<tr ng-repeat="product in ctrl.vendorProducts">
|
||||||
|
<td ng-if="product.product_type == 0"><a ui-sref="distro({id: product.id})">{{product.name}}</a></td>
|
||||||
|
<td ng-if="product.product_type != 0"><a ui-sref="cloud({id: product.id})">{{product.name}}</a></td>
|
||||||
|
<td>{{ctrl.getProductTypeDescription(product.product_type)}}</td>
|
||||||
|
<td>{{product.description}}</td>
|
||||||
|
<td>{{product.public ? 'Public' : 'Private'}}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -35,6 +35,8 @@
|
|||||||
|
|
||||||
ctrl.getVendor = getVendor;
|
ctrl.getVendor = getVendor;
|
||||||
ctrl.getVendorUsers = getVendorUsers;
|
ctrl.getVendorUsers = getVendorUsers;
|
||||||
|
ctrl.getVendorProducts = getVendorProducts;
|
||||||
|
ctrl.getProductTypeDescription = getProductTypeDescription;
|
||||||
ctrl.registerVendor = registerVendor;
|
ctrl.registerVendor = registerVendor;
|
||||||
ctrl.approveVendor = approveVendor;
|
ctrl.approveVendor = approveVendor;
|
||||||
ctrl.declineVendor = declineVendor;
|
ctrl.declineVendor = declineVendor;
|
||||||
@ -51,6 +53,10 @@
|
|||||||
$state.go('home');
|
$state.go('home');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ctrl.getVendor();
|
||||||
|
ctrl.getVendorUsers();
|
||||||
|
ctrl.getVendorProducts();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This will contact the Refstack API to get a vendor information.
|
* This will contact the Refstack API to get a vendor information.
|
||||||
*/
|
*/
|
||||||
@ -77,7 +83,6 @@
|
|||||||
angular.toJson(error);
|
angular.toJson(error);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
ctrl.getVendor();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This will 'send' application for registration.
|
* This will 'send' application for registration.
|
||||||
@ -152,7 +157,40 @@
|
|||||||
angular.toJson(error);
|
angular.toJson(error);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
ctrl.getVendorUsers();
|
|
||||||
|
/**
|
||||||
|
* Updates list of users in the vendor's group
|
||||||
|
*/
|
||||||
|
function getVendorProducts() {
|
||||||
|
ctrl.showError = false;
|
||||||
|
var contentUrl = refstackApiUrl + '/products?organization_id='
|
||||||
|
+ ctrl.vendorId;
|
||||||
|
ctrl.productsRequest =
|
||||||
|
$http.get(contentUrl).success(function(data) {
|
||||||
|
ctrl.vendorProducts = data.products;
|
||||||
|
}).error(function(error) {
|
||||||
|
ctrl.showError = true;
|
||||||
|
ctrl.error =
|
||||||
|
'Error retrieving from server: ' +
|
||||||
|
angular.toJson(error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the product type description given the type integer.
|
||||||
|
*/
|
||||||
|
function getProductTypeDescription(product_type) {
|
||||||
|
switch (product_type) {
|
||||||
|
case 0:
|
||||||
|
return 'Distro';
|
||||||
|
case 1:
|
||||||
|
return 'Public Cloud';
|
||||||
|
case 2:
|
||||||
|
return 'Hosted Private Cloud';
|
||||||
|
default:
|
||||||
|
return 'Unknown';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes user with specific openid from vendor's group
|
* Removes user with specific openid from vendor's group
|
||||||
|
@ -849,6 +849,7 @@ describe('Refstack controllers', function () {
|
|||||||
var fakeResp = {'id': 'fake-id', 'type': 1,
|
var fakeResp = {'id': 'fake-id', 'type': 1,
|
||||||
'can_manage': true, 'properties' : {}};
|
'can_manage': true, 'properties' : {}};
|
||||||
var fakeUsersResp = [{'openid': 'foo'}];
|
var fakeUsersResp = [{'openid': 'foo'}];
|
||||||
|
var fakeProdResp = {'products': [{'id': 123}]};
|
||||||
var fakeWindow = {
|
var fakeWindow = {
|
||||||
location: {
|
location: {
|
||||||
href: ''
|
href: ''
|
||||||
@ -871,6 +872,8 @@ describe('Refstack controllers', function () {
|
|||||||
$httpBackend.when('GET', fakeApiUrl +
|
$httpBackend.when('GET', fakeApiUrl +
|
||||||
'/vendors/1234').respond(fakeResp);
|
'/vendors/1234').respond(fakeResp);
|
||||||
$httpBackend.when('GET', fakeApiUrl +
|
$httpBackend.when('GET', fakeApiUrl +
|
||||||
|
'/products?organization_id=1234').respond(fakeProdResp);
|
||||||
|
$httpBackend.when('GET', fakeApiUrl +
|
||||||
'/vendors/1234/users').respond(fakeUsersResp);
|
'/vendors/1234/users').respond(fakeUsersResp);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@ -893,6 +896,14 @@ describe('Refstack controllers', function () {
|
|||||||
expect(ctrl.currentUser).toEqual('foo');
|
expect(ctrl.currentUser).toEqual('foo');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should have a function to get vendor products',
|
||||||
|
function () {
|
||||||
|
ctrl.vendorProducts = null;
|
||||||
|
ctrl.getVendorProducts();
|
||||||
|
$httpBackend.flush();
|
||||||
|
expect(ctrl.vendorProducts).toEqual(fakeProdResp.products);
|
||||||
|
});
|
||||||
|
|
||||||
it('should have a function to register a vendor',
|
it('should have a function to register a vendor',
|
||||||
function () {
|
function () {
|
||||||
$httpBackend.expectPOST(
|
$httpBackend.expectPOST(
|
||||||
|
@ -142,25 +142,33 @@ class ProductsController(validation.BaseRestControllerWithValidation):
|
|||||||
@pecan.expose('json')
|
@pecan.expose('json')
|
||||||
def get(self):
|
def get(self):
|
||||||
"""Get information of all products."""
|
"""Get information of all products."""
|
||||||
|
filters = api_utils.parse_input_params(['organization_id'])
|
||||||
|
|
||||||
allowed_keys = ['id', 'name', 'description', 'product_ref_id', 'type',
|
allowed_keys = ['id', 'name', 'description', 'product_ref_id', 'type',
|
||||||
'product_type', 'public', 'organization_id']
|
'product_type', 'public', 'organization_id']
|
||||||
user = api_utils.get_user_id()
|
user = api_utils.get_user_id()
|
||||||
is_admin = user in db.get_foundation_users()
|
is_admin = user in db.get_foundation_users()
|
||||||
try:
|
try:
|
||||||
if is_admin:
|
if is_admin:
|
||||||
products = db.get_products(allowed_keys=allowed_keys)
|
products = db.get_products(allowed_keys=allowed_keys,
|
||||||
|
filters=filters)
|
||||||
for s in products:
|
for s in products:
|
||||||
s['can_manage'] = True
|
s['can_manage'] = True
|
||||||
else:
|
else:
|
||||||
result = dict()
|
result = dict()
|
||||||
products = db.get_public_products(allowed_keys=allowed_keys)
|
filters['public'] = True
|
||||||
|
|
||||||
|
products = db.get_products(allowed_keys=allowed_keys,
|
||||||
|
filters=filters)
|
||||||
for s in products:
|
for s in products:
|
||||||
_id = s['id']
|
_id = s['id']
|
||||||
result[_id] = s
|
result[_id] = s
|
||||||
result[_id]['can_manage'] = False
|
result[_id]['can_manage'] = False
|
||||||
|
|
||||||
|
filters.pop('public')
|
||||||
products = db.get_products_by_user(user,
|
products = db.get_products_by_user(user,
|
||||||
allowed_keys=allowed_keys)
|
allowed_keys=allowed_keys,
|
||||||
|
filters=filters)
|
||||||
for s in products:
|
for s in products:
|
||||||
_id = s['id']
|
_id = s['id']
|
||||||
if _id not in result:
|
if _id not in result:
|
||||||
|
@ -246,19 +246,15 @@ def get_organizations_by_user(user_openid, allowed_keys=None):
|
|||||||
allowed_keys=allowed_keys)
|
allowed_keys=allowed_keys)
|
||||||
|
|
||||||
|
|
||||||
def get_public_products(allowed_keys=None):
|
def get_products(allowed_keys=None, filters=None):
|
||||||
"""Get all public products."""
|
|
||||||
return IMPL.get_public_products(allowed_keys=allowed_keys)
|
|
||||||
|
|
||||||
|
|
||||||
def get_products(allowed_keys=None):
|
|
||||||
"""Get all products."""
|
"""Get all products."""
|
||||||
return IMPL.get_products(allowed_keys=allowed_keys)
|
return IMPL.get_products(allowed_keys=allowed_keys, filters=filters)
|
||||||
|
|
||||||
|
|
||||||
def get_products_by_user(user_openid, allowed_keys=None):
|
def get_products_by_user(user_openid, allowed_keys=None, filters=None):
|
||||||
"""Get all products that user can manage."""
|
"""Get all products that user can manage."""
|
||||||
return IMPL.get_products_by_user(user_openid, allowed_keys=allowed_keys)
|
return IMPL.get_products_by_user(user_openid, allowed_keys=allowed_keys,
|
||||||
|
filters=filters)
|
||||||
|
|
||||||
|
|
||||||
def get_product_by_version(product_version_id, allowed_keys=None):
|
def get_product_by_version(product_version_id, allowed_keys=None):
|
||||||
|
@ -602,29 +602,31 @@ def get_organizations_by_user(user_openid, allowed_keys=None):
|
|||||||
return _to_dict(items, allowed_keys=allowed_keys)
|
return _to_dict(items, allowed_keys=allowed_keys)
|
||||||
|
|
||||||
|
|
||||||
def get_public_products(allowed_keys=None):
|
def get_products(allowed_keys=None, filters=None):
|
||||||
"""Get public products."""
|
"""Get products based on passed in filters."""
|
||||||
|
if filters is None:
|
||||||
|
filters = {}
|
||||||
|
expected_filters = ['public', 'organization_id']
|
||||||
|
filter_args = {}
|
||||||
|
for key, value in six.iteritems(filters):
|
||||||
|
if key not in expected_filters:
|
||||||
|
raise Exception('Unknown filter key "%s"' % key)
|
||||||
|
filter_args[key] = value
|
||||||
|
|
||||||
session = get_session()
|
session = get_session()
|
||||||
items = (
|
query = session.query(models.Product)
|
||||||
session.query(models.Product)
|
if filter_args:
|
||||||
.filter_by(public=True)
|
query = query.filter_by(**filter_args)
|
||||||
.order_by(models.Product.created_at.desc()).all())
|
items = query.order_by(models.Product.created_at.desc()).all()
|
||||||
return _to_dict(items, allowed_keys=allowed_keys)
|
return _to_dict(items, allowed_keys=allowed_keys)
|
||||||
|
|
||||||
|
|
||||||
def get_products(allowed_keys=None):
|
def get_products_by_user(user_openid, allowed_keys=None, filters=None):
|
||||||
"""Get all products."""
|
"""Get products that a user can manage."""
|
||||||
|
if filters is None:
|
||||||
|
filters = {}
|
||||||
session = get_session()
|
session = get_session()
|
||||||
items = (
|
query = (
|
||||||
session.query(models.Product)
|
|
||||||
.order_by(models.Product.created_at.desc()).all())
|
|
||||||
return _to_dict(items, allowed_keys=allowed_keys)
|
|
||||||
|
|
||||||
|
|
||||||
def get_products_by_user(user_openid, allowed_keys=None):
|
|
||||||
"""Get all products that user can manage."""
|
|
||||||
session = get_session()
|
|
||||||
items = (
|
|
||||||
session.query(models.Product, models.Organization, models.Group,
|
session.query(models.Product, models.Organization, models.Group,
|
||||||
models.UserToGroup)
|
models.UserToGroup)
|
||||||
.join(models.Organization,
|
.join(models.Organization,
|
||||||
@ -633,8 +635,15 @@ def get_products_by_user(user_openid, allowed_keys=None):
|
|||||||
models.Group.id == models.Organization.group_id)
|
models.Group.id == models.Organization.group_id)
|
||||||
.join(models.UserToGroup,
|
.join(models.UserToGroup,
|
||||||
models.Group.id == models.UserToGroup.group_id)
|
models.Group.id == models.UserToGroup.group_id)
|
||||||
.filter(models.UserToGroup.user_openid == user_openid)
|
.filter(models.UserToGroup.user_openid == user_openid))
|
||||||
.order_by(models.Organization.created_at.desc()).all())
|
|
||||||
|
expected_filters = ['organization_id']
|
||||||
|
for key, value in six.iteritems(filters):
|
||||||
|
if key not in expected_filters:
|
||||||
|
raise Exception('Unknown filter key "%s"' % key)
|
||||||
|
query = query.filter(getattr(models.Product, key) ==
|
||||||
|
filters[key])
|
||||||
|
items = query.order_by(models.Organization.created_at.desc()).all()
|
||||||
items = [item[0] for item in items]
|
items = [item[0] for item in items]
|
||||||
return _to_dict(items, allowed_keys=allowed_keys)
|
return _to_dict(items, allowed_keys=allowed_keys)
|
||||||
|
|
||||||
|
@ -108,6 +108,36 @@ class TestProductsEndpoint(api.FunctionalTest):
|
|||||||
product = json.dumps(FAKE_PRODUCT)
|
product = json.dumps(FAKE_PRODUCT)
|
||||||
post_response = self.post_json(self.URL, params=product)
|
post_response = self.post_json(self.URL, params=product)
|
||||||
|
|
||||||
|
@mock.patch('refstack.api.utils.get_user_id', return_value='test-open-id')
|
||||||
|
def test_get_by_org(self, mock_get_user):
|
||||||
|
"""Test getting products of an organization."""
|
||||||
|
org1 = db.add_organization({'name': 'test-vendor1'}, 'test-open-id')
|
||||||
|
org2 = db.add_organization({'name': 'test-vendor2'}, 'test-open-id')
|
||||||
|
prod_info = {'name': 'product1',
|
||||||
|
'description': 'product description',
|
||||||
|
'product_type': 1, 'type': 0,
|
||||||
|
'organization_id': org1['id'], 'public': True}
|
||||||
|
prod1 = db.add_product(prod_info, 'test-open-id')
|
||||||
|
prod_info['name'] = 'product2'
|
||||||
|
prod_info['organization_id'] = org2['id']
|
||||||
|
prod2 = db.add_product(prod_info, 'test-open-id')
|
||||||
|
get_response = self.get_json(self.URL +
|
||||||
|
'?organization_id=' + org1['id'])
|
||||||
|
self.assertEqual(1, len(get_response['products']))
|
||||||
|
self.assertEqual(prod1['id'], get_response['products'][0]['id'])
|
||||||
|
|
||||||
|
get_response = self.get_json(self.URL +
|
||||||
|
'?organization_id=' + org2['id'])
|
||||||
|
self.assertEqual(1, len(get_response['products']))
|
||||||
|
self.assertEqual(prod2['id'], get_response['products'][0]['id'])
|
||||||
|
|
||||||
|
# Test that non-admin can't view non-public products of an org.
|
||||||
|
db.update_product({'id': prod1['id'], 'public': False})
|
||||||
|
mock_get_user.return_value = 'some-user'
|
||||||
|
get_response = self.get_json(self.URL +
|
||||||
|
'?organization_id=' + org1['id'])
|
||||||
|
self.assertFalse(get_response['products'])
|
||||||
|
|
||||||
@mock.patch('refstack.api.utils.get_user_id', return_value='test-open-id')
|
@mock.patch('refstack.api.utils.get_user_id', return_value='test-open-id')
|
||||||
def test_get_one(self, mock_get_user):
|
def test_get_one(self, mock_get_user):
|
||||||
"""Test get_one request."""
|
"""Test get_one request."""
|
||||||
|
Loading…
x
Reference in New Issue
Block a user