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>
|
||||
<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>
|
||||
|
||||
|
@ -35,6 +35,8 @@
|
||||
|
||||
ctrl.getVendor = getVendor;
|
||||
ctrl.getVendorUsers = getVendorUsers;
|
||||
ctrl.getVendorProducts = getVendorProducts;
|
||||
ctrl.getProductTypeDescription = getProductTypeDescription;
|
||||
ctrl.registerVendor = registerVendor;
|
||||
ctrl.approveVendor = approveVendor;
|
||||
ctrl.declineVendor = declineVendor;
|
||||
@ -51,6 +53,10 @@
|
||||
$state.go('home');
|
||||
}
|
||||
|
||||
ctrl.getVendor();
|
||||
ctrl.getVendorUsers();
|
||||
ctrl.getVendorProducts();
|
||||
|
||||
/**
|
||||
* This will contact the Refstack API to get a vendor information.
|
||||
*/
|
||||
@ -77,7 +83,6 @@
|
||||
angular.toJson(error);
|
||||
});
|
||||
}
|
||||
ctrl.getVendor();
|
||||
|
||||
/**
|
||||
* This will 'send' application for registration.
|
||||
@ -152,7 +157,40 @@
|
||||
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
|
||||
|
@ -849,6 +849,7 @@ describe('Refstack controllers', function () {
|
||||
var fakeResp = {'id': 'fake-id', 'type': 1,
|
||||
'can_manage': true, 'properties' : {}};
|
||||
var fakeUsersResp = [{'openid': 'foo'}];
|
||||
var fakeProdResp = {'products': [{'id': 123}]};
|
||||
var fakeWindow = {
|
||||
location: {
|
||||
href: ''
|
||||
@ -871,6 +872,8 @@ describe('Refstack controllers', function () {
|
||||
$httpBackend.when('GET', fakeApiUrl +
|
||||
'/vendors/1234').respond(fakeResp);
|
||||
$httpBackend.when('GET', fakeApiUrl +
|
||||
'/products?organization_id=1234').respond(fakeProdResp);
|
||||
$httpBackend.when('GET', fakeApiUrl +
|
||||
'/vendors/1234/users').respond(fakeUsersResp);
|
||||
}));
|
||||
|
||||
@ -893,6 +896,14 @@ describe('Refstack controllers', function () {
|
||||
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',
|
||||
function () {
|
||||
$httpBackend.expectPOST(
|
||||
|
@ -142,25 +142,33 @@ class ProductsController(validation.BaseRestControllerWithValidation):
|
||||
@pecan.expose('json')
|
||||
def get(self):
|
||||
"""Get information of all products."""
|
||||
filters = api_utils.parse_input_params(['organization_id'])
|
||||
|
||||
allowed_keys = ['id', 'name', 'description', 'product_ref_id', 'type',
|
||||
'product_type', 'public', 'organization_id']
|
||||
user = api_utils.get_user_id()
|
||||
is_admin = user in db.get_foundation_users()
|
||||
try:
|
||||
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:
|
||||
s['can_manage'] = True
|
||||
else:
|
||||
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:
|
||||
_id = s['id']
|
||||
result[_id] = s
|
||||
result[_id]['can_manage'] = False
|
||||
|
||||
filters.pop('public')
|
||||
products = db.get_products_by_user(user,
|
||||
allowed_keys=allowed_keys)
|
||||
allowed_keys=allowed_keys,
|
||||
filters=filters)
|
||||
for s in products:
|
||||
_id = s['id']
|
||||
if _id not in result:
|
||||
|
@ -246,19 +246,15 @@ def get_organizations_by_user(user_openid, allowed_keys=None):
|
||||
allowed_keys=allowed_keys)
|
||||
|
||||
|
||||
def get_public_products(allowed_keys=None):
|
||||
"""Get all public products."""
|
||||
return IMPL.get_public_products(allowed_keys=allowed_keys)
|
||||
|
||||
|
||||
def get_products(allowed_keys=None):
|
||||
def get_products(allowed_keys=None, filters=None):
|
||||
"""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."""
|
||||
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):
|
||||
|
@ -602,29 +602,31 @@ def get_organizations_by_user(user_openid, allowed_keys=None):
|
||||
return _to_dict(items, allowed_keys=allowed_keys)
|
||||
|
||||
|
||||
def get_public_products(allowed_keys=None):
|
||||
"""Get public products."""
|
||||
def get_products(allowed_keys=None, filters=None):
|
||||
"""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()
|
||||
items = (
|
||||
session.query(models.Product)
|
||||
.filter_by(public=True)
|
||||
.order_by(models.Product.created_at.desc()).all())
|
||||
query = session.query(models.Product)
|
||||
if filter_args:
|
||||
query = query.filter_by(**filter_args)
|
||||
items = query.order_by(models.Product.created_at.desc()).all()
|
||||
return _to_dict(items, allowed_keys=allowed_keys)
|
||||
|
||||
|
||||
def get_products(allowed_keys=None):
|
||||
"""Get all products."""
|
||||
def get_products_by_user(user_openid, allowed_keys=None, filters=None):
|
||||
"""Get products that a user can manage."""
|
||||
if filters is None:
|
||||
filters = {}
|
||||
session = get_session()
|
||||
items = (
|
||||
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 = (
|
||||
query = (
|
||||
session.query(models.Product, models.Organization, models.Group,
|
||||
models.UserToGroup)
|
||||
.join(models.Organization,
|
||||
@ -633,8 +635,15 @@ def get_products_by_user(user_openid, allowed_keys=None):
|
||||
models.Group.id == models.Organization.group_id)
|
||||
.join(models.UserToGroup,
|
||||
models.Group.id == models.UserToGroup.group_id)
|
||||
.filter(models.UserToGroup.user_openid == user_openid)
|
||||
.order_by(models.Organization.created_at.desc()).all())
|
||||
.filter(models.UserToGroup.user_openid == user_openid))
|
||||
|
||||
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]
|
||||
return _to_dict(items, allowed_keys=allowed_keys)
|
||||
|
||||
|
@ -108,6 +108,36 @@ class TestProductsEndpoint(api.FunctionalTest):
|
||||
product = json.dumps(FAKE_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')
|
||||
def test_get_one(self, mock_get_user):
|
||||
"""Test get_one request."""
|
||||
|
Loading…
x
Reference in New Issue
Block a user