def __init__(self, credentials=None, domain=None): consumer_key = credentials and credentials["key"] or None consumer_secret = credentials and credentials["secret"] or None domain = domain or DEFAULT_DOMAIN self._client = Client(domain=domain, consumer_key=consumer_key, consumer_secret=consumer_secret)
def __init__(self, credentials=None, domain=None): consumer_key = credentials and credentials["key"] or None consumer_secret = credentials and credentials["secret"] or None domain = domain or DEFAULT_DOMAIN self._client = Client( domain=domain, consumer_key=consumer_key, consumer_secret=consumer_secret)
class MarketplaceAPI: def __init__(self, credentials=None, domain=None): consumer_key = credentials and credentials["key"] or None consumer_secret = credentials and credentials["secret"] or None domain = domain or DEFAULT_DOMAIN self._client = Client( domain=domain, consumer_key=consumer_key, consumer_secret=consumer_secret) def submit_app(self, mock_app): #validate app manifest self._validate_manifest(mock_app) #create app self._create_app(mock_app) # update the app with the mock app data self.update_app_data(mock_app) # Add screenshot to app self.add_screenshot(mock_app) #change status to pending self.change_app_status_to_pending(mock_app) def _validate_manifest(self, mock_app): response = self._client.validate_manifest(mock_app['url']) manifest_validation_id = json.loads(response.content)['id'] # validate manifest validation_report = self._client.is_manifest_valid(manifest_validation_id) Assert.true(validation_report, "The manifest url is not valid.\n Validation report:\n %s" % validation_report) mock_app['manifest_validation_id'] = manifest_validation_id def _create_app(self, mock_app): # create app using the manifest response = self._client.create(mock_app.manifest_validation_id) Assert.equal(response.status_code, 201, "Invalid status code.\n Status code received is: %s" % response.status_code) mock_app['id'] = json.loads(response.content)['id'] def update_app_data(self, mock_app): # update the default app data with the custom mock app information data = { 'name': mock_app.name, 'summary': mock_app.summary, 'categories': [], 'support_email': mock_app.support_email, 'device_types': [], 'payment_type': mock_app.payment_type, 'premium_type': 'free', 'privacy_policy': mock_app.privacy_policy, 'description': mock_app.description, 'homepage': mock_app.homepage, 'support_url': mock_app.support_website } # device_types: a list of the device types at least one of: 'desktop', 'android-tablet', 'android-mobile', 'firefoxos' data['device_types'] = [device[0] for device in mock_app['device_type'] if device[1]] Assert.true(data['device_types'], 'insufficient data added device_types') # categories: a list of the categories, at least two of the category ids provided from the category api data['categories'] = [category['id'] for category in self._categories if category['name'] in [mock_category[0] for mock_category in mock_app.categories]] Assert.greater_equal(len(data['categories']), 2, 'Insufficient data added categories == %s\n Minimum 2 categories required' % data['categories']) response = self._client.update(mock_app.id, data) Assert.equal(response.status_code, 202, "Update app data failed.\n Status code %s" % response.status_code) def add_screenshot(self, mock_app): response = self._client.create_screenshot(app_id=mock_app.id, filename=mock_app["screenshot_link"], position=1) Assert.equal(response.status_code, 201, "Screenshot not valid.\n Status code %s\nResponse data %s" % (response.status_code, json.loads(response.content))) @property def _categories(self): return json.loads(self._client.get_categories().content)['objects'] def delete_app(self, mock_app): # Not yet implemented: https://bugzilla.mozilla.org/show_bug.cgi?id=816572 response = self._client.delete(mock_app.id) Assert.equal(response.status_code, 204, 'Delete app failed') def app_status(self, mock_app): response = self._client.status(mock_app.id) Assert.equal(response.status_code, 200, "App status failed\n Status code: %s" % response.status_code) return json.loads(response.content) @property def all_apps(self): response = self._client.list_webapps() Assert.equal(response.status_code, 200, "Get all apps failed\n Status code: %s" % response.status_code) return json.loads(response.content)['objects'] def change_app_status_to_pending(self, mock_app): self.change_app_state(mock_app, state='pending') def change_app_state(self, mock_app, state): response = self._client.app_state(app_id=mock_app.id, status=state) Assert.equal(response.status_code, 202, "App state change failed\n Status code: %s" % response.status_code) def submit_app_review(self, app_id, review, rating): from urlparse import urlunparse client = self._client endpoint = '/apps/rating/' _url = urlunparse((client.protocol, '%s:%s' % (client.domain, client.port), '%s/api/v1%s' % (client.prefix, endpoint), '', '', '')) response = self._client.conn.fetch('POST', _url, { 'app': app_id, 'body': review, 'rating': rating, }) response = json.loads(response.text) return response['resource_uri'].split('/')[-2] def get_app_review(self, app_id=None, app_slug=None, user='******'): if app_id is None and app_slug is None: raise ValueError('Provide either app_id or app_slug.') from urlparse import urlunparse client = self._client endpoint = '/apps/rating/?app=%s&user=%s' % (app_slug if app_slug is not None else app_id, user) _url = urlunparse((client.protocol, '%s:%s' % (client.domain, client.port), '%s/api/v1%s' % (client.prefix, endpoint), '', '', '')) resp = self._client.conn.fetch('GET', _url) return json.loads(resp.text) def submit_app_review_for_either(self, apps, review, rating): from requests.exceptions import HTTPError from datetime import datetime # Get app details apps_details = {} for app in apps: apps_details.update({ app: self.get_app(app), }) # try submitting review for one app for app_name, app in apps_details.iteritems(): # Submit a review using marketplace API try: review_id = self.submit_app_review(app['id'], review, rating) selected_app = app_name except HTTPError, e: continue break # if none of the apps have a review, then use the review that got # submitted eariler if locals().get('review_id', None) is None: reviews = [] # find app that has a review and return that for app_name, app in apps_details.iteritems(): reviews.append(self.get_app_review(app['id'])) # compare submission time of both the reviews and select the one # that got submitted first first = datetime.strptime(reviews[0]['objects'][0]['modified'], '%Y-%m-%dT%H:%M:%S') second = datetime.strptime(reviews[1]['objects'][0]['modified'], '%Y-%m-%dT%H:%M:%S') if first > second: selected_app = apps_details.keys()[1] review_id = reviews[1]['objects'][0]['resource_uri'].split('/')[-2] else: selected_app = apps_details.keys()[0] review_id = reviews[0]['objects'][0]['resource_uri'].split('/')[-2] return (selected_app, review_id)
def main(): parser = argparse.ArgumentParser( description='Reviewer onboarding data loader') parser.add_argument('url', type=str, help='url of marketplace') parser.add_argument('apiKey', type=str, help='api key to use') parser.add_argument('apiSecret', type=str, help='api secret') args = parser.parse_args() scheme, netloc = urlparse.urlparse(args.url)[:2] domain, _, port = netloc.partition(':') c = Client( domain=domain, protocol=scheme, port=int(port) if port else 80, consumer_key=args.apiKey, consumer_secret=args.apiSecret) appdir = os.path.join(os.path.dirname(__file__), 'reviewer_apps') apps = [json.load(open(os.path.join(appdir, appf))) for appf in os.listdir(appdir) if appf.endswith('.json')] def validate(url): response = c.validate_manifest(url) if response.status_code == 201: return json.loads(response.content)['id'] else: raise RuntimeError('Failed to submit app %s for validation: %s' % ( url, response.status_code)) validation_ids = [validate(app['manifest_url']) for app in apps] pending = set(validation_ids) while pending: for manifest_id in list(pending): response = c.get_manifest_validation_result(manifest_id) if response.status_code != 200: raise RuntimeError('Validation failure %s: %s' % ( manifest_id, response.status_code)) else: content = json.loads(response.content) if content['processed']: if content['valid']: pending.remove(manifest_id) else: raise RuntimeError('Validation failed %s: %s' % ( manifest_id, content)) appids = [] def creat(validation_id): response = c.create(validation_id) content = json.loads(response.content) if response.status_code != 201: raise RuntimeError("Failed to create app %s: %s" % ( validation_id, response.status_code)) return content['id'] appids = [creat(vid) for vid in validation_ids] for (app_id, app) in zip(appids, apps): response = c.update( app_id, { 'name': 'App %d' % (app_id,), 'summary': 'App %d' % (app_id,), 'categories': app['categories'], 'support_email': '*****@*****.**', 'device_types': app['device_types'], 'privacy_policy': app['privacy_policy'], 'premium_type': 'free', }) if response.status_code != 202: raise RuntimeError("App update failed %s: %s" % ( app_id, response.status_code)) c.create_screenshot(app_id, os.path.join(appdir, "screenshot.png")) c.add_content_ratings(app_id, 0, 0)
class MarketplaceAPI: def __init__(self, credentials=None, domain=None): consumer_key = credentials and credentials["key"] or None consumer_secret = credentials and credentials["secret"] or None domain= domain or DEFAULT_DOMAIN self._client = Client( domain=domain, consumer_key=consumer_key, consumer_secret=consumer_secret) def submit_app(self, mock_app): #validate app manifest self._validate_manifest(mock_app) #create app self._create_app(mock_app) # update the app with the mock app data self.update_app_data(mock_app) # Add screenshot to app self.add_screenshot(mock_app) #change status to pending self.change_app_status_to_pending(mock_app) def _validate_manifest(self, mock_app): response = self._client.validate_manifest(mock_app['url']) manifest_validation_id = json.loads(response.content)['id'] # validate manifest validation_report = self._client.is_manifest_valid(manifest_validation_id) Assert.true(validation_report, "The manifest url is not valid.\n Validation report:\n %s" %validation_report) mock_app['manifest_validation_id'] = manifest_validation_id def _create_app(self, mock_app): # create app using the manifest response = self._client.create(mock_app.manifest_validation_id) Assert.equal(response.status_code, 201, "Invalid status code.\n Status code received is: %s" %response.status_code) mock_app['id'] = json.loads(response.content)['id'] def update_app_data(self, mock_app): # update the default app data with the custom mock app information data = { 'name': mock_app.name, 'summary': mock_app.summary, 'categories': [], 'support_email': mock_app.support_email, 'device_types': [], 'payment_type': mock_app.payment_type, 'premium_type': 'free', 'privacy_policy': mock_app.privacy_policy, 'description': mock_app.description, 'homepage': mock_app.homepage, 'support_url': mock_app.support_website } # device_types: a list of the device types at least one of: 'desktop', 'android-tablet', 'android-mobile', 'firefoxos' data['device_types'] = [device[0] for device in mock_app['device_type'] if device[1]] Assert.true(data['device_types'], 'insufficient data added device_types') # categories: a list of the categories, at least two of the category ids provided from the category api data['categories'] = [category['id'] for category in self._categories if category['name'] in [mock_category[0] for mock_category in mock_app.categories]] Assert.greater_equal(len(data['categories']), 2, 'Insufficient data added categories == %s\n Minimum 2 categories required' % data['categories']) response = self._client.update(mock_app.id, data) Assert.equal(response.status_code, 202, "Update app data failed.\n Status code %s" %response.status_code) def add_screenshot(self, mock_app): response = self._client.create_screenshot(app_id=mock_app.id, filename=mock_app["screenshot_link"], position=1) Assert.equal(response.status_code, 201, "Screenshot not valid.\n Status code %s\nResponse data %s" %(response.status_code, json.loads(response.content))) @property def _categories(self): return json.loads(self._client.get_categories().content)['objects'] def delete_app(self, mock_app): # Not yet implemented: https://bugzilla.mozilla.org/show_bug.cgi?id=816572 response = self._client.delete(mock_app.id) Assert.equal(response.status_code, 204, 'Delete app failed') def app_status(self, mock_app): response = self._client.status(mock_app.id) Assert.equal(response.status_code, 200, "App status failed\n Status code: %s" % response.status_code) return json.loads(response.content) @property def all_apps(self): response = self._client.list_webapps() Assert.equal(response.status_code, 200, "Get all apps failed\n Status code: %s" % response.status_code) return json.loads(response.content)['objects'] def change_app_status_to_pending(self, mock_app): self.change_app_state(mock_app, state='pending') def change_app_state(self, mock_app, state): response = self._client.app_state(app_id=mock_app.id, status=state) Assert.equal(response.status_code, 202, "App state change failed\n Status code: %s" % response.status_code)
class MarketplaceAPI: def __init__(self, credentials=None, domain=None): consumer_key = credentials and credentials["key"] or None consumer_secret = credentials and credentials["secret"] or None domain = domain or DEFAULT_DOMAIN self._client = Client(domain=domain, consumer_key=consumer_key, consumer_secret=consumer_secret) def submit_app(self, mock_app): #validate app manifest self._validate_manifest(mock_app) #create app self._create_app(mock_app) # update the app with the mock app data self.update_app_data(mock_app) # Add screenshot to app self.add_screenshot(mock_app) #change status to pending self.change_app_status_to_pending(mock_app) def _validate_manifest(self, mock_app): response = self._client.validate_manifest(mock_app['url']) manifest_validation_id = json.loads(response.content)['id'] # validate manifest validation_report = self._client.is_manifest_valid( manifest_validation_id) Assert.true( validation_report, "The manifest url is not valid.\n Validation report:\n %s" % validation_report) mock_app['manifest_validation_id'] = manifest_validation_id def _create_app(self, mock_app): # create app using the manifest response = self._client.create(mock_app.manifest_validation_id) Assert.equal( response.status_code, 201, "Invalid status code.\n Status code received is: %s" % response.status_code) mock_app['id'] = json.loads(response.content)['id'] def update_app_data(self, mock_app): # update the default app data with the custom mock app information data = { 'name': mock_app.name, 'summary': mock_app.summary, 'categories': [], 'support_email': mock_app.support_email, 'device_types': [], 'payment_type': mock_app.payment_type, 'premium_type': 'free', 'privacy_policy': mock_app.privacy_policy, 'description': mock_app.description, 'homepage': mock_app.homepage, 'support_url': mock_app.support_website } # device_types: a list of the device types at least one of: 'desktop', 'android-tablet', 'android-mobile', 'firefoxos' data['device_types'] = [ device[0] for device in mock_app['device_type'] if device[1] ] Assert.true(data['device_types'], 'insufficient data added device_types') # categories: a list of the categories, at least two of the category ids provided from the category api data['categories'] = [ category['id'] for category in self._categories if category['name'] in [mock_category[0] for mock_category in mock_app.categories] ] Assert.greater_equal( len(data['categories']), 2, 'Insufficient data added categories == %s\n Minimum 2 categories required' % data['categories']) response = self._client.update(mock_app.id, data) Assert.equal( response.status_code, 202, "Update app data failed.\n Status code %s" % response.status_code) def add_screenshot(self, mock_app): response = self._client.create_screenshot( app_id=mock_app.id, filename=mock_app["screenshot_link"], position=1) Assert.equal( response.status_code, 201, "Screenshot not valid.\n Status code %s\nResponse data %s" % (response.status_code, json.loads(response.content))) @property def _categories(self): return json.loads(self._client.get_categories().content)['objects'] def delete_app(self, mock_app): # Not yet implemented: https://bugzilla.mozilla.org/show_bug.cgi?id=816572 response = self._client.delete(mock_app.id) Assert.equal(response.status_code, 204, 'Delete app failed') def app_status(self, mock_app): response = self._client.status(mock_app.id) Assert.equal( response.status_code, 200, "App status failed\n Status code: %s" % response.status_code) return json.loads(response.content) @property def all_apps(self): response = self._client.list_webapps() Assert.equal( response.status_code, 200, "Get all apps failed\n Status code: %s" % response.status_code) return json.loads(response.content)['objects'] def change_app_status_to_pending(self, mock_app): self.change_app_state(mock_app, state='pending') def change_app_state(self, mock_app, state): response = self._client.app_state(app_id=mock_app.id, status=state) Assert.equal( response.status_code, 202, "App state change failed\n Status code: %s" % response.status_code) def submit_app_review(self, app_id, review, rating): from urlparse import urlunparse client = self._client endpoint = '/apps/rating/' _url = urlunparse( (client.protocol, '%s:%s' % (client.domain, client.port), '%s/api/v1%s' % (client.prefix, endpoint), '', '', '')) response = self._client.conn.fetch('POST', _url, { 'app': app_id, 'body': review, 'rating': rating, }) response = json.loads(response.text) return response['resource_uri'].split('/')[-2] def get_app_review(self, app_id=None, app_slug=None, user='******'): if app_id is None and app_slug is None: raise ValueError('Provide either app_id or app_slug.') from urlparse import urlunparse client = self._client endpoint = '/apps/rating/?app=%s&user=%s' % ( app_slug if app_slug is not None else app_id, user) _url = urlunparse( (client.protocol, '%s:%s' % (client.domain, client.port), '%s/api/v1%s' % (client.prefix, endpoint), '', '', '')) resp = self._client.conn.fetch('GET', _url) return json.loads(resp.text) def submit_app_review_for_either(self, apps, review, rating): from requests.exceptions import HTTPError from datetime import datetime # Get app details apps_details = {} for app in apps: apps_details.update({ app: self.get_app(app), }) # try submitting review for one app for app_name, app in apps_details.iteritems(): # Submit a review using marketplace API try: review_id = self.submit_app_review(app['id'], review, rating) selected_app = app_name except HTTPError, e: continue break # if none of the apps have a review, then use the review that got # submitted eariler if locals().get('review_id', None) is None: reviews = [] # find app that has a review and return that for app_name, app in apps_details.iteritems(): reviews.append(self.get_app_review(app['id'])) # compare submission time of both the reviews and select the one # that got submitted first first = datetime.strptime(reviews[0]['objects'][0]['modified'], '%Y-%m-%dT%H:%M:%S') second = datetime.strptime(reviews[1]['objects'][0]['modified'], '%Y-%m-%dT%H:%M:%S') if first > second: selected_app = apps_details.keys()[1] review_id = reviews[1]['objects'][0]['resource_uri'].split( '/')[-2] else: selected_app = apps_details.keys()[0] review_id = reviews[0]['objects'][0]['resource_uri'].split( '/')[-2] return (selected_app, review_id)
class MarketplaceAPI: def __init__(self, credentials=None, domain=None): consumer_key = credentials and credentials["key"] or None consumer_secret = credentials and credentials["secret"] or None domain = domain or DEFAULT_DOMAIN self._client = Client(domain=domain, consumer_key=consumer_key, consumer_secret=consumer_secret) def submit_app(self, mock_app): #validate app manifest self._validate_manifest(mock_app) #create app self._create_app(mock_app) # update the app with the mock app data self.update_app_data(mock_app) # Add screenshot to app self.add_screenshot(mock_app) #change status to pending self.change_app_status_to_pending(mock_app) def _validate_manifest(self, mock_app): response = self._client.validate_manifest(mock_app['url']) manifest_validation_id = json.loads(response.content)['id'] # validate manifest validation_report = self._client.is_manifest_valid( manifest_validation_id) Assert.true( validation_report, "The manifest url is not valid.\n Validation report:\n %s" % validation_report) mock_app['manifest_validation_id'] = manifest_validation_id def _create_app(self, mock_app): # create app using the manifest response = self._client.create(mock_app.manifest_validation_id) Assert.equal( response.status_code, 201, "Invalid status code.\n Status code received is: %s" % response.status_code) mock_app['id'] = json.loads(response.content)['id'] def update_app_data(self, mock_app): # update the default app data with the custom mock app information data = { 'name': mock_app.name, 'summary': mock_app.summary, 'categories': [], 'support_email': mock_app.support_email, 'device_types': [], 'payment_type': mock_app.payment_type, 'premium_type': 'free', 'privacy_policy': mock_app.privacy_policy, 'description': mock_app.description, 'homepage': mock_app.homepage, 'support_url': mock_app.support_website } # device_types: a list of the device types at least one of: 'desktop', 'android-tablet', 'android-mobile', 'firefoxos' data['device_types'] = [ device[0] for device in mock_app['device_type'] if device[1] ] Assert.true(data['device_types'], 'insufficient data added device_types') # categories: a list of the categories, at least two of the category ids provided from the category api data['categories'] = [ category['id'] for category in self._categories if category['name'] in [mock_category[0] for mock_category in mock_app.categories] ] Assert.greater_equal( len(data['categories']), 2, 'Insufficient data added categories == %s\n Minimum 2 categories required' % data['categories']) response = self._client.update(mock_app.id, data) Assert.equal( response.status_code, 202, "Update app data failed.\n Status code %s" % response.status_code) def add_screenshot(self, mock_app): response = self._client.create_screenshot( app_id=mock_app.id, filename=mock_app["screenshot_link"], position=1) Assert.equal( response.status_code, 201, "Screenshot not valid.\n Status code %s\nResponse data %s" % (response.status_code, json.loads(response.content))) @property def _categories(self): return json.loads(self._client.get_categories().content)['objects'] def delete_app(self, mock_app): # Not yet implemented: https://bugzilla.mozilla.org/show_bug.cgi?id=816572 response = self._client.delete(mock_app.id) Assert.equal(response.status_code, 204, 'Delete app failed') def app_status(self, mock_app): response = self._client.status(mock_app.id) Assert.equal( response.status_code, 200, "App status failed\n Status code: %s" % response.status_code) return json.loads(response.content) @property def all_apps(self): response = self._client.list_webapps() Assert.equal( response.status_code, 200, "Get all apps failed\n Status code: %s" % response.status_code) return json.loads(response.content)['objects'] def change_app_status_to_pending(self, mock_app): self.change_app_state(mock_app, state='pending') def change_app_state(self, mock_app, state): response = self._client.app_state(app_id=mock_app.id, status=state) Assert.equal( response.status_code, 202, "App state change failed\n Status code: %s" % response.status_code) def submit_app_review(self, app_id, review, rating): from urlparse import urlunparse client = self._client endpoint = '/apps/rating/' _url = urlunparse( (client.protocol, '%s:%s' % (client.domain, client.port), '%s/api/v1%s' % (client.prefix, endpoint), '', '', '')) response = self._client.conn.fetch('POST', _url, { 'app': app_id, 'body': review, 'rating': rating, }) response = json.loads(response.text) return response['resource_uri'].split('/')[-2] def submit_app_review_for_either(self, apps, review, rating): from requests.exceptions import HTTPError for selected_app in apps: # Get the app's details app = self.get_app(selected_app) # Submit a review using marketplace API try: review_id = self.submit_app_review(app['id'], review, rating) except HTTPError: continue break if locals().get('review_id', None) is None: raise Exception('Both the apps already have reviews. Delete them ' 'and run the test again.') return (selected_app, review_id) def delete_app_review(self, review_id): from urlparse import urlunparse client = self._client endpoint = '/apps/rating/%s/' % review_id _url = urlunparse( (client.protocol, '%s:%s' % (client.domain, client.port), '%s/api/v1%s' % (client.prefix, endpoint), '', '', '')) return self._client.conn.fetch('DELETE', _url) def get_app(self, app): response = self._client.conn.fetch('GET', self._client.url('app') % app) response = json.loads(response.text) return response
class MarketplaceAPI: def __init__(self, credentials=None, domain=None): consumer_key = credentials and credentials["key"] or None consumer_secret = credentials and credentials["secret"] or None domain = domain or DEFAULT_DOMAIN self._client = Client( domain=domain, consumer_key=consumer_key, consumer_secret=consumer_secret) def submit_app(self, mock_app): #validate app manifest self._validate_manifest(mock_app) #create app self._create_app(mock_app) # update the app with the mock app data self.update_app_data(mock_app) # Add screenshot to app self.add_screenshot(mock_app) #change status to pending self.change_app_status_to_pending(mock_app) def _validate_manifest(self, mock_app): response = self._client.validate_manifest(mock_app['url']) manifest_validation_id = json.loads(response.content)['id'] # validate manifest validation_report = self._client.is_manifest_valid(manifest_validation_id) Assert.true(validation_report, "The manifest url is not valid.\n Validation report:\n %s" % validation_report) mock_app['manifest_validation_id'] = manifest_validation_id def _create_app(self, mock_app): # create app using the manifest response = self._client.create(mock_app.manifest_validation_id) Assert.equal(response.status_code, 201, "Invalid status code.\n Status code received is: %s" % response.status_code) mock_app['id'] = json.loads(response.content)['id'] def update_app_data(self, mock_app): # update the default app data with the custom mock app information data = { 'name': mock_app.name, 'summary': mock_app.summary, 'categories': [], 'support_email': mock_app.support_email, 'device_types': [], 'payment_type': mock_app.payment_type, 'premium_type': 'free', 'privacy_policy': mock_app.privacy_policy, 'description': mock_app.description, 'homepage': mock_app.homepage, 'support_url': mock_app.support_website } # device_types: a list of the device types at least one of: 'desktop', 'android-tablet', 'android-mobile', 'firefoxos' data['device_types'] = [device[0] for device in mock_app['device_type'] if device[1]] Assert.true(data['device_types'], 'insufficient data added device_types') # categories: a list of the categories, at least two of the category ids provided from the category api data['categories'] = [category['id'] for category in self._categories if category['name'] in [mock_category[0] for mock_category in mock_app.categories]] Assert.greater_equal(len(data['categories']), 2, 'Insufficient data added categories == %s\n Minimum 2 categories required' % data['categories']) response = self._client.update(mock_app.id, data) Assert.equal(response.status_code, 202, "Update app data failed.\n Status code %s" % response.status_code) def add_screenshot(self, mock_app): response = self._client.create_screenshot(app_id=mock_app.id, filename=mock_app["screenshot_link"], position=1) Assert.equal(response.status_code, 201, "Screenshot not valid.\n Status code %s\nResponse data %s" % (response.status_code, json.loads(response.content))) @property def _categories(self): return json.loads(self._client.get_categories().content)['objects'] def delete_app(self, mock_app): # Not yet implemented: https://bugzilla.mozilla.org/show_bug.cgi?id=816572 response = self._client.delete(mock_app.id) Assert.equal(response.status_code, 204, 'Delete app failed') def app_status(self, mock_app): response = self._client.status(mock_app.id) Assert.equal(response.status_code, 200, "App status failed\n Status code: %s" % response.status_code) return json.loads(response.content) @property def all_apps(self): response = self._client.list_webapps() Assert.equal(response.status_code, 200, "Get all apps failed\n Status code: %s" % response.status_code) return json.loads(response.content)['objects'] def change_app_status_to_pending(self, mock_app): self.change_app_state(mock_app, state='pending') def change_app_state(self, mock_app, state): response = self._client.app_state(app_id=mock_app.id, status=state) Assert.equal(response.status_code, 202, "App state change failed\n Status code: %s" % response.status_code) def submit_app_review(self, app_id, review, rating): from urlparse import urlunparse client = self._client endpoint = '/apps/rating/' _url = urlunparse((client.protocol, '%s:%s' % (client.domain, client.port), '%s/api/v1%s' % (client.prefix, endpoint), '', '', '')) response = self._client.conn.fetch('POST', _url, { 'app': app_id, 'body': review, 'rating': rating, }) response = json.loads(response.text) return response['resource_uri'].split('/')[-2] def submit_app_review_for_either(self, apps, review, rating): from requests.exceptions import HTTPError for selected_app in apps: # Get the app's details app = self.get_app(selected_app) # Submit a review using marketplace API try: review_id = self.submit_app_review(app['id'], review, rating) except HTTPError: continue break if locals().get('review_id', None) is None: raise Exception('Both the apps already have reviews. Delete them ' 'and run the test again.') return (selected_app, review_id) def delete_app_review(self, review_id): from urlparse import urlunparse client = self._client endpoint = '/apps/rating/%s/' % review_id _url = urlunparse((client.protocol, '%s:%s' % (client.domain, client.port), '%s/api/v1%s' % (client.prefix, endpoint), '', '', '')) return self._client.conn.fetch('DELETE', _url) def get_app(self, app): response = self._client.conn.fetch('GET', self._client.url('app') % app) response = json.loads(response.text) return response @staticmethod def get_client(base_url, credentials): api_keys = MarketplaceAPI.get_credentials(base_url, credentials) client = MarketplaceAPI(credentials=api_keys) if 'dev' not in base_url: client = MarketplaceAPI(credentials=api_keys, domain='marketplace.allizom.org') return client @staticmethod def get_credentials(base_url, credentials): if 'dev' in base_url: return credentials['api-dev'] else: return credentials['api-stage']
def __init__(self, key, secret, domain=None): domain = domain or DEFAULT_DOMAIN self._client = Client( domain=domain, consumer_key=key, consumer_secret=secret)
class MarketplaceAPI: def __init__(self, key, secret, domain=None): domain = domain or DEFAULT_DOMAIN self._client = Client( domain=domain, consumer_key=key, consumer_secret=secret) def submit_app(self, app): # validate app manifest self._validate_manifest(app) # create app self._create_app(app) # update the app with the mock app data self.update_app_data(app) # Add screenshot to app self.add_screenshot(app) # Add content ratings to app, which automatically updates the status to pending self.add_content_ratings(app) def _validate_manifest(self, app): response = self._client.validate_manifest(app['url']) manifest_validation_id = json.loads(response.content)['id'] # validate manifest validation_report = self._client.is_manifest_valid(manifest_validation_id) # FIXME: This assert is suspicious assert validation_report, 'The manifest url is not valid.\n Validation report:\n %s' % validation_report app['manifest_validation_id'] = manifest_validation_id def _create_app(self, app): # create app using the manifest response = self._client.create(app.manifest_validation_id) assert requests.codes.created == response.status_code, 'Invalid status code.' app_dict = json.loads(response.content) app['id'] = app_dict['id'] app['url_end'] = app_dict['slug'] def update_app_data(self, app): # update the default app data with the custom mock app information data = { 'name': app.name, 'summary': app.summary, 'categories': [], 'support_email': app.support_email, 'device_types': [], 'payment_type': app.payment_type, 'premium_type': 'free', 'privacy_policy': app.privacy_policy, 'description': app.description, 'homepage': app.homepage, 'support_url': app.support_website } # device_types: a list of the device types at least one of: 'desktop', 'android-tablet', 'android-mobile', 'firefoxos' data['device_types'] = [device[0] for device in app['device_type'] if device[1]] assert data['device_types'], 'Insufficient data added to device_types' # categories: a list of the categories, at least two of the category ids provided from the category api data['categories'] = [category['slug'] for category in self._categories if category['name'] in [mock_category[0] for mock_category in app.categories]] assert len(data['categories']) >= 2, 'Insufficient data added to categories == %s\n Minimum 2 categories required' % data['categories'] response = self._client.update(app.id, data) assert requests.codes.accepted == response.status_code, 'Update app data failed.' def add_screenshot(self, app): response = self._client.create_screenshot(app_id=app.id, filename=app["screenshot_link"], position=1) assert requests.codes.created == response.status_code, 'Screenshot not valid.\nResponse data %s' % json.loads(response.content) def add_content_ratings(self, app): response = self._client.add_content_ratings( app_id=app.id, submission_id=app.submission_id, security_code=app.security_code) try: response_data = json.loads(response.content) except ValueError: response_data = 'Unknown' assert requests.codes.created == response.status_code, 'Content ratings not added.\nResponse data %s' % response_data @property def _categories(self): return json.loads(self._client.get_categories().content)['objects'] def delete_app(self, app): response = self._client.delete(app.id) assert requests.codes.no_content == response.status_code, 'Delete app failed' def app_status(self, app): response = self._client.status(app.id) assert requests.codes.ok == response.status_code, 'App status failed' return json.loads(response.content) @property def all_apps(self): response = self._client.list_webapps() assert requests.codes.ok == response.status_code, 'Get all apps failed' return json.loads(response.content)['objects'] def change_app_status_to_pending(self, app): self.change_app_state(app, state='pending') def change_app_state(self, app, state): response = self._client.app_state(app_id=app.id, status=state) assert requests.codes.accepted == response.status_code, 'App state change failed' def submit_app_review(self, app_id, review, rating): from urlparse import urlunparse client = self._client endpoint = '/apps/rating/' _url = urlunparse((client.protocol, '%s:%s' % (client.domain, client.port), '%s/api/v1%s' % (client.prefix, endpoint), '', '', '')) response = self._client.conn.fetch('POST', _url, { 'app': app_id, 'body': review, 'rating': rating, }) response = json.loads(response.text) return response['resource_uri'].split('/')[-2] def get_app_review(self, app_id=None, app_slug=None, user='******'): if app_id is None and app_slug is None: raise ValueError('Provide either app_id or app_slug.') from urlparse import urlunparse client = self._client endpoint = '/apps/rating/?app=%s&user=%s' % (app_slug if app_slug is not None else app_id, user) _url = urlunparse((client.protocol, '%s:%s' % (client.domain, client.port), '%s/api/v1%s' % (client.prefix, endpoint), '', '', '')) resp = self._client.conn.fetch('GET', _url) return json.loads(resp.text) def submit_app_review_for_either(self, apps, review, rating): from requests.exceptions import HTTPError from datetime import datetime # Get app details apps_details = {} for app in apps: apps_details.update({ app: self.get_app(app), }) # try submitting review for one app for app_name, app in apps_details.iteritems(): # Submit a review using marketplace API try: review_id = self.submit_app_review(app['id'], review, rating) selected_app = app_name except HTTPError, e: continue break # if none of the apps have a review, then use the review that got # submitted eariler if locals().get('review_id', None) is None: reviews = [] # find app that has a review and return that for app_name, app in apps_details.iteritems(): reviews.append(self.get_app_review(app['id'])) # compare submission time of both the reviews and select the one # that got submitted first first = datetime.strptime(reviews[0]['objects'][0]['modified'], '%Y-%m-%dT%H:%M:%S') second = datetime.strptime(reviews[1]['objects'][0]['modified'], '%Y-%m-%dT%H:%M:%S') if first > second: selected_app = apps_details.keys()[1] review_id = reviews[1]['objects'][0]['resource_uri'].split('/')[-2] else: selected_app = apps_details.keys()[0] review_id = reviews[0]['objects'][0]['resource_uri'].split('/')[-2] return (selected_app, review_id)
def __init__(self, key, secret, domain=None): domain = domain or DEFAULT_DOMAIN self._client = Client(domain=domain, consumer_key=key, consumer_secret=secret)
class MarketplaceAPI: def __init__(self, credentials=None, domain=None): consumer_key = credentials and credentials["key"] or None consumer_secret = credentials and credentials["secret"] or None domain = domain or DEFAULT_DOMAIN self._client = Client(domain=domain, consumer_key=consumer_key, consumer_secret=consumer_secret) def submit_app(self, mock_app): #validate app manifest self._validate_manifest(mock_app) #create app self._create_app(mock_app) # update the app with the mock app data self.update_app_data(mock_app) # Add screenshot to app self.add_screenshot(mock_app) #change status to pending self.change_app_status_to_pending(mock_app) def _validate_manifest(self, mock_app): response = self._client.validate_manifest(mock_app['url']) manifest_validation_id = json.loads(response.content)['id'] # validate manifest validation_report = self._client.is_manifest_valid( manifest_validation_id) Assert.true( validation_report, "The manifest url is not valid.\n Validation report:\n %s" % validation_report) mock_app['manifest_validation_id'] = manifest_validation_id def _create_app(self, mock_app): # create app using the manifest response = self._client.create(mock_app.manifest_validation_id) Assert.equal( response.status_code, 201, "Invalid status code.\n Status code received is: %s" % response.status_code) mock_app['id'] = json.loads(response.content)['id'] def update_app_data(self, mock_app): # update the default app data with the custom mock app information data = { 'name': mock_app.name, 'summary': mock_app.summary, 'categories': [], 'support_email': mock_app.support_email, 'device_types': [], 'payment_type': mock_app.payment_type, 'premium_type': 'free', 'privacy_policy': mock_app.privacy_policy, 'description': mock_app.description, 'homepage': mock_app.homepage, 'support_url': mock_app.support_website } # device_types: a list of the device types at least one of: 'desktop', 'android-tablet', 'android-mobile', 'firefoxos' data['device_types'] = [ device[0] for device in mock_app['device_type'] if device[1] ] Assert.true(data['device_types'], 'insufficient data added device_types') # categories: a list of the categories, at least two of the category ids provided from the category api data['categories'] = [ category['id'] for category in self._categories if category['name'] in [mock_category[0] for mock_category in mock_app.categories] ] Assert.greater_equal( len(data['categories']), 2, 'Insufficient data added categories == %s\n Minimum 2 categories required' % data['categories']) response = self._client.update(mock_app.id, data) Assert.equal( response.status_code, 202, "Update app data failed.\n Status code %s" % response.status_code) def add_screenshot(self, mock_app): response = self._client.create_screenshot( app_id=mock_app.id, filename=mock_app["screenshot_link"], position=1) Assert.equal( response.status_code, 201, "Screenshot not valid.\n Status code %s\nResponse data %s" % (response.status_code, json.loads(response.content))) @property def _categories(self): return json.loads(self._client.get_categories().content)['objects'] def delete_app(self, mock_app): # Not yet implemented: https://bugzilla.mozilla.org/show_bug.cgi?id=816572 response = self._client.delete(mock_app.id) Assert.equal(response.status_code, 204, 'Delete app failed') def app_status(self, mock_app): response = self._client.status(mock_app.id) Assert.equal( response.status_code, 200, "App status failed\n Status code: %s" % response.status_code) return json.loads(response.content) @property def all_apps(self): response = self._client.list_webapps() Assert.equal( response.status_code, 200, "Get all apps failed\n Status code: %s" % response.status_code) return json.loads(response.content)['objects'] def change_app_status_to_pending(self, mock_app): self.change_app_state(mock_app, state='pending') def change_app_state(self, mock_app, state): response = self._client.app_state(app_id=mock_app.id, status=state) Assert.equal( response.status_code, 202, "App state change failed\n Status code: %s" % response.status_code)
class MarketplaceAPI: def __init__(self, key, secret, domain=None): domain = domain or DEFAULT_DOMAIN self._client = Client(domain=domain, consumer_key=key, consumer_secret=secret) def submit_app(self, app): # validate app manifest self._validate_manifest(app) # create app self._create_app(app) # update the app with the mock app data self.update_app_data(app) # Add screenshot to app self.add_screenshot(app) # Add content ratings to app, which automatically updates the status to pending self.add_content_ratings(app) def _validate_manifest(self, app): response = self._client.validate_manifest(app['url']) manifest_validation_id = json.loads(response.content)['id'] # validate manifest validation_report = self._client.is_manifest_valid( manifest_validation_id) # FIXME: This assert is suspicious assert validation_report, 'The manifest url is not valid.\n Validation report:\n %s' % validation_report app['manifest_validation_id'] = manifest_validation_id def _create_app(self, app): # create app using the manifest response = self._client.create(app.manifest_validation_id) assert requests.codes.created == response.status_code, 'Invalid status code.' app_dict = json.loads(response.content) app['id'] = app_dict['id'] app['url_end'] = app_dict['slug'] def update_app_data(self, app): # update the default app data with the custom mock app information data = { 'name': app.name, 'summary': app.summary, 'categories': [], 'support_email': app.support_email, 'device_types': [], 'payment_type': app.payment_type, 'premium_type': 'free', 'privacy_policy': app.privacy_policy, 'description': app.description, 'homepage': app.homepage, 'support_url': app.support_website } # device_types: a list of the device types at least one of: 'desktop', 'android-tablet', 'android-mobile', 'firefoxos' data['device_types'] = [ device[0] for device in app['device_type'] if device[1] ] assert data['device_types'], 'Insufficient data added to device_types' # categories: a list of the categories, at least two of the category ids provided from the category api data['categories'] = [ category['slug'] for category in self._categories if category['name'] in [mock_category[0] for mock_category in app.categories] ] assert len( data['categories'] ) >= 2, 'Insufficient data added to categories == %s\n Minimum 2 categories required' % data[ 'categories'] response = self._client.update(app.id, data) assert requests.codes.accepted == response.status_code, 'Update app data failed.' def add_screenshot(self, app): response = self._client.create_screenshot( app_id=app.id, filename=app["screenshot_link"], position=1) assert requests.codes.created == response.status_code, 'Screenshot not valid.\nResponse data %s' % json.loads( response.content) def add_content_ratings(self, app): response = self._client.add_content_ratings( app_id=app.id, submission_id=app.submission_id, security_code=app.security_code) try: response_data = json.loads(response.content) except ValueError: response_data = 'Unknown' assert requests.codes.created == response.status_code, 'Content ratings not added.\nResponse data %s' % response_data @property def _categories(self): return json.loads(self._client.get_categories().content)['objects'] def delete_app(self, app): response = self._client.delete(app.id) assert requests.codes.no_content == response.status_code, 'Delete app failed' def app_status(self, app): response = self._client.status(app.id) assert requests.codes.ok == response.status_code, 'App status failed' return json.loads(response.content) @property def all_apps(self): response = self._client.list_webapps() assert requests.codes.ok == response.status_code, 'Get all apps failed' return json.loads(response.content)['objects'] def change_app_status_to_pending(self, app): self.change_app_state(app, state='pending') def change_app_state(self, app, state): response = self._client.app_state(app_id=app.id, status=state) assert requests.codes.accepted == response.status_code, 'App state change failed' def submit_app_review(self, app_id, review, rating): from urlparse import urlunparse client = self._client endpoint = '/apps/rating/' _url = urlunparse( (client.protocol, '%s:%s' % (client.domain, client.port), '%s/api/v1%s' % (client.prefix, endpoint), '', '', '')) response = self._client.conn.fetch('POST', _url, { 'app': app_id, 'body': review, 'rating': rating, }) response = json.loads(response.text) return response['resource_uri'].split('/')[-2] def get_app_review(self, app_id=None, app_slug=None, user='******'): if app_id is None and app_slug is None: raise ValueError('Provide either app_id or app_slug.') from urlparse import urlunparse client = self._client endpoint = '/apps/rating/?app=%s&user=%s' % ( app_slug if app_slug is not None else app_id, user) _url = urlunparse( (client.protocol, '%s:%s' % (client.domain, client.port), '%s/api/v1%s' % (client.prefix, endpoint), '', '', '')) resp = self._client.conn.fetch('GET', _url) return json.loads(resp.text) def submit_app_review_for_either(self, apps, review, rating): from requests.exceptions import HTTPError from datetime import datetime # Get app details apps_details = {} for app in apps: apps_details.update({ app: self.get_app(app), }) # try submitting review for one app for app_name, app in apps_details.iteritems(): # Submit a review using marketplace API try: review_id = self.submit_app_review(app['id'], review, rating) selected_app = app_name except HTTPError, e: continue break # if none of the apps have a review, then use the review that got # submitted eariler if locals().get('review_id', None) is None: reviews = [] # find app that has a review and return that for app_name, app in apps_details.iteritems(): reviews.append(self.get_app_review(app['id'])) # compare submission time of both the reviews and select the one # that got submitted first first = datetime.strptime(reviews[0]['objects'][0]['modified'], '%Y-%m-%dT%H:%M:%S') second = datetime.strptime(reviews[1]['objects'][0]['modified'], '%Y-%m-%dT%H:%M:%S') if first > second: selected_app = apps_details.keys()[1] review_id = reviews[1]['objects'][0]['resource_uri'].split( '/')[-2] else: selected_app = apps_details.keys()[0] review_id = reviews[0]['objects'][0]['resource_uri'].split( '/')[-2] return (selected_app, review_id)