def new_volume(short_name): """Add a new volume.""" category = project_repo.get_category_by(short_name=short_name) if not category: # pragma: no cover abort(404) ensure_authorized_to('update', category) volumes = category.info.get('volumes', []) form = VolumeForm(request.body) form.category_id.data = category.id all_importers = importer.get_all_importer_names() form.importer.choices = [(name, name) for name in all_importers] new_vol = None if request.method == 'POST' and form.validate(): volume_id = str(uuid.uuid4()) new_vol = dict(id=volume_id, name=form.name.data, short_name=form.short_name.data, importer=form.importer.data) volumes.append(new_vol) category.info['volumes'] = volumes project_repo.update_category(category) flash("Volume added", 'success') elif request.method == 'POST': # pragma: no cover flash('Please correct the errors', 'error') response = dict(form=form, new_volume=new_vol, all_importers=all_importers) return handle_content_type(response)
def test_project_created_with_correct_details(self, mock_importer): """Test that a project is created with the correct details.""" self.register(name=Fixtures.name) self.signin() vol = dict(id='123abc', name='My Volume') category = CategoryFactory() tmpl_fixtures = TemplateFixtures(category) select_task = tmpl_fixtures.iiif_select_tmpl tmpl = tmpl_fixtures.create(task_tmpl=select_task) category.info = dict(presenter='iiif-annotation', volumes=[vol], templates=[tmpl]) project_repo.update_category(category) endpoint = '/lc/projects/{}/new'.format(category.short_name) form_data = dict(name='foo', short_name='bar', template_id=tmpl['id'], volume_id=vol['id']) res = self.app_post_json(endpoint, data=form_data) project = project_repo.get(1) # Check project details assert_equal(project.name, form_data['name']) assert_equal(project.short_name, form_data['short_name']) assert_equal(project.webhook, 'http://localhost/lc/analysis') assert_equal(project.published, True) assert_equal(project.description, tmpl['description']) assert_dict_equal(project.info, { 'template_id': tmpl['id'], 'volume_id': vol['id'] })
def test_new_project_task_redundancy_updated(self, mock_importer, mock_update_redundancy): """Test task redundancy updated for new projects.""" self.register(name=Fixtures.name) self.signin() min_answers = 10 vol = dict(id='123abc', name='My Volume') category = CategoryFactory() tmpl_fixtures = TemplateFixtures(category) select_task = tmpl_fixtures.iiif_select_tmpl tmpl = tmpl_fixtures.create(task_tmpl=select_task) tmpl['min_answers'] = min_answers category.info = dict(presenter='iiif-annotation', volumes=[vol], templates=[tmpl]) project_repo.update_category(category) endpoint = '/lc/projects/{}/new'.format(category.short_name) form_data = dict(name='foo', short_name='bar', template_id=tmpl['id'], volume_id=vol['id']) self.app_post_json(endpoint, data=form_data) project = project_repo.get(1) mock_update_redundancy.assert_called_once_with(project, min_answers)
def test_child_projects_not_built_from_non_iiif_templates(self): """Test that only IIIF projects can be built from parents.""" self.register() user = user_repo.get(1) vol = dict(id='123abc', name='My Volume', importer='foo') category = CategoryFactory() tmpl_fixtures = TemplateFixtures(category) select_task = tmpl_fixtures.iiif_select_tmpl parent_tmpl = tmpl_fixtures.create(task_tmpl=select_task) child_tmpl = tmpl_fixtures.create(task_tmpl=select_task) child_tmpl['parent_template_id'] = parent_tmpl['id'] category.info = dict(presenter='iiif-annotation', volumes=[vol], templates=[parent_tmpl, child_tmpl]) project_repo.update_category(category) parent = ProjectFactory(owner=user, category=category, info=dict(template_id=parent_tmpl['id'], volume_id=vol['id'])) endpoint = '/lc/projects/{}/new'.format(category.short_name) form_data = dict(name='foo', short_name='bar', template_id=child_tmpl['id'], volume_id=vol['id']) res = self.app_post_json(endpoint, data=form_data) res_data = json.loads(res.data) msg = 'Only IIIF projects can be built from parents.' assert_equal(res_data['flash'], msg)
def test_project_created_with_volume_avatar(self, mock_importer): """Test that a project is created with the volume's avatar.""" self.register() self.signin() vol = dict(id='123abc', name='My Volume', container='foo', thumbnail='bar.png', thumbnail_url='/foo/bar.png') category = CategoryFactory() tmpl_fixtures = TemplateFixtures(category) select_task = tmpl_fixtures.iiif_select_tmpl tmpl = tmpl_fixtures.create(task_tmpl=select_task) category.info = dict(presenter='iiif-annotation', volumes=[vol], templates=[tmpl]) project_repo.update_category(category) endpoint = '/lc/projects/{}/new'.format(category.short_name) form_data = dict(name='foo', short_name='bar', template_id=tmpl['id'], volume_id=vol['id']) res = self.app_post_json(endpoint, data=form_data) project = project_repo.get(1) # Check project avatar details assert_equal(project.info['container'], vol['container']) assert_equal(project.info['thumbnail'], vol['thumbnail']) assert_equal(project.info['thumbnail_url'], vol['thumbnail_url'])
def test_z3950_project_creation(self, mock_importer): """Test that a Z39.50 project is created.""" mock_importer.count_tasks_to_import.return_value = 1 self.register() self.signin() vol = dict(id='123abc', name='My Volume', importer='z3950', data=dict(album_id=self.flickr_album_id)) category = CategoryFactory() tmpl_fixtures = TemplateFixtures(category) z3950_task = tmpl_fixtures.z3950_tmpl tmpl = tmpl_fixtures.create(task_tmpl=z3950_task) category.info = dict(presenter='z3950', volumes=[vol], templates=[tmpl]) project_repo.update_category(category) endpoint = '/lc/projects/{}/new'.format(category.short_name) form_data = dict(name='foo', short_name='bar', template_id=tmpl['id'], volume_id=vol['id']) res = self.app_post_json(endpoint, data=form_data) res_data = json.loads(res.data) msg = 'The project was generated with 1 task.' assert_equal(res_data['flash'], msg) project = project_repo.get(1) # Check correct task data imported expected = call(task_repo, project.id, type='z3950', album_id=self.flickr_album_id) assert_equal(mock_importer.create_tasks.call_args_list, [expected])
def update(): """Helper function to update the current volume.""" try: idx = [ i for i, _vol in enumerate(volumes) if _vol['id'] == volume_id ][0] except IndexError: # pragma: no cover abort(404) volumes[idx] = volume category.info['volumes'] = volumes project_repo.update_category(category)
def test_project_built_from_valid_parent_template(self, mock_count, mock_create_tasks): """Test that import data modified for IIIF child projects.""" self.register() user = user_repo.get(1) vol = dict(id='123abc', name='My Volume', importer='iiif', data=dict(manifest_uri=self.manifest_uri)) category = CategoryFactory() tmpl_fixtures = TemplateFixtures(category) select_task = tmpl_fixtures.iiif_select_tmpl parent_tmpl = tmpl_fixtures.create(task_tmpl=select_task) child_tmpl = tmpl_fixtures.create(task_tmpl=select_task) child_tmpl['parent_template_id'] = parent_tmpl['id'] category.info = dict(presenter='iiif-annotation', volumes=[vol], templates=[parent_tmpl, child_tmpl]) project_repo.update_category(category) parent = ProjectFactory(id=42, owner=user, category=category, info=dict(template_id=parent_tmpl['id'], volume_id=vol['id'])) n_tasks = 3 tasks = TaskFactory.create_batch(n_tasks, n_answers=1, project=parent) for task in tasks: TaskRunFactory.create(user=user, project=parent, task=task) results = result_repo.filter_by(project_id=parent.id) for result in results: result.info = 'foo' result_repo.update(result) endpoint = '/lc/projects/{}/new'.format(category.short_name) form_data = dict(name='foo', short_name='bar', template_id=child_tmpl['id'], volume_id=vol['id']) self.app_post_json(endpoint, data=form_data) expected_call = call(task_repo, 1, type='iiif-enhanced', manifest_uri=self.manifest_uri, parent_id=parent.id) assert_equal(mock_create_tasks.call_args_list, [expected_call])
def test_child_projects_not_built_from_incomplete_parents(self): """Test that child projects are not built from incomplete parents.""" self.register() user = user_repo.get(1) vol = dict(id='123abc', name='My Volume', importer='iiif') category = CategoryFactory() tmpl_fixtures = TemplateFixtures(category) select_task = tmpl_fixtures.iiif_select_tmpl parent_tmpl = tmpl_fixtures.create(task_tmpl=select_task) child_tmpl = tmpl_fixtures.create(task_tmpl=select_task) child_tmpl['parent_template_id'] = parent_tmpl['id'] category.info = dict(presenter='iiif-annotation', volumes=[vol], templates=[parent_tmpl, child_tmpl]) project_repo.update_category(category) parent = ProjectFactory(owner=user, category=category, info=dict(template_id=parent_tmpl['id'], volume_id=vol['id'])) n_tasks = 3 tasks = TaskFactory.create_batch(n_tasks, n_answers=1, project=parent) endpoint = '/lc/projects/{}/new'.format(category.short_name) form_data = dict(name='foo', short_name='bar', template_id=child_tmpl['id'], volume_id=vol['id']) # Check parent with incomplete tasks and results res = self.app_post_json(endpoint, data=form_data) res_data = json.loads(res.data) msg = 'There is no valid parent for this template and volume.' assert_equal(res_data['flash'], msg) # Check parent with incomplete results for task in tasks: TaskRunFactory.create(user=user, project=parent, task=task) res = self.app_post_json(endpoint, data=form_data) res_data = json.loads(res.data) msg = 'There is no valid parent for this template and volume.' assert_equal(res_data['flash'], msg)
def update_category(id): """Update a category.""" try: category = project_repo.get_category(id) if category: ensure_authorized_to('update', category) form = CategoryForm(obj=category) form.populate_obj(category) if request.method == 'GET': response = dict(template='admin/update_category.html', title=gettext('Update Category'), category=category, form=form) return handle_content_type(response) if request.method == 'POST': form = CategoryForm(request.body) if form.validate(): slug = form.name.data.lower().replace(" ", "") new_category = Category(id=form.id.data, name=form.name.data, short_name=slug) project_repo.update_category(new_category) cached_cat.reset() msg = gettext("Category updated") flash(msg, 'success') return redirect_content_type(url_for(".categories")) else: msg = gettext("Please correct the errors") flash(msg, 'success') response = dict(template='admin/update_category.html', title=gettext('Update Category'), category=category, form=form) return handle_content_type(response) else: abort(404) except HTTPException: raise except Exception as e: # pragma: no cover current_app.logger.error(e) return abort(500)
def update_category(id): """Update a category.""" try: category = project_repo.get_category(id) if category: ensure_authorized_to('update', category) form = CategoryForm(obj=category) form.populate_obj(category) if request.method == 'GET': response = dict(template='admin/update_category.html', title=gettext('Update Category'), category=category, form=form) return handle_content_type(response) if request.method == 'POST': form = CategoryForm(request.body) if form.validate(): slug = form.name.data.lower().replace(" ", "") new_category = Category(id=form.id.data, name=form.name.data, short_name=slug) project_repo.update_category(new_category) cached_cat.reset() msg = gettext("Category updated") flash(msg, 'success') return redirect_content_type(url_for(".categories")) else: msg = gettext("Please correct the errors") flash(msg, 'success') response = dict(template='admin/update_category.html', title=gettext('Update Category'), category=category, form=form) return handle_content_type(response) else: abort(404) except HTTPException: raise except Exception as e: # pragma: no cover current_app.logger.error(e) return abort(500)