def am_updatesite(annroot, userhome, options): """ Update site data, leaving user data alone annroot is the root directory for the Annalist software installation. userhome is the home directory for the host system user issuing the command. options contains options parsed from the command line. returns 0 if all is well, or a non-zero status code. This value is intended to be used as an exit status code for the calling program. """ status = am_errors.AM_SUCCESS sitesettings = am_get_site_settings(annroot, userhome, options) if not sitesettings: print("Settings not found (%s)"%(options.configuration), file=sys.stderr) return am_errors.AM_NOSETTINGS if len(options.args) > 0: print( "Unexpected arguments for %s: (%s)"% (options.command, " ".join(options.args)), file=sys.stderr ) return am_errors.AM_UNEXPECTEDARGS site_layout = layout.Layout(sitesettings.BASE_DATA_DIR, sitesettings.SITE_DIR_NAME) sitebasedir = site_layout.SITE_PATH sitebaseurl = "/annalist/" # @@TODO: figure more robust way to define this site = Site(sitebaseurl, site_layout.SITE_PATH) sitedata = site.site_data_collection(test_exists=False) if sitedata is None: print("Initializing Annalist site metadata in %s (migrating to new layout)"%(sitebasedir)) site = Site.create_site_metadata( sitebaseurl, sitebasedir, label="Annalist site (%s configuration)"%options.configuration, description="Annalist %s site metadata and site-wide values."%options.configuration ) sitedata = site.site_data_collection() site_data_src = os.path.join(annroot, "annalist/data/sitedata") # @@TODO: more robust definition site_data_tgt, site_data_file = sitedata._dir_path() # --- Migrate old site data to new site directory # _annalist_site/ site_data_old1 = os.path.join(sitebasedir, site_layout.SITEDATA_OLD_DIR1) old_site_metadata = os.path.join(site_data_old1, site_layout.SITE_META_FILE) old_site_database = os.path.join(site_data_old1, site_layout.SITE_DATABASE_FILE) old_users1 = os.path.join(site_data_old1, layout.USER_DIR_PREV) old_vocabs1 = os.path.join(site_data_old1, layout.VOCAB_DIR_PREV) if os.path.isfile(old_site_metadata): print("Move old site metadata: %s -> %s"%(old_site_metadata, sitebasedir)) new_site_metadata = os.path.join(sitebasedir, site_layout.SITE_META_FILE) os.rename(old_site_metadata, new_site_metadata) if os.path.isfile(old_site_database): print("Move old site database: %s -> %s"%(old_site_database, sitebasedir)) new_site_database = os.path.join(sitebasedir, site_layout.SITE_DATABASE_FILE) os.rename(old_site_database, new_site_database) if os.path.isdir(old_users1) or os.path.isdir(old_vocabs1): print("Copy Annalist old user and/or vocab data from %s"%site_data_old1) migrate_old_data(site_data_old1, layout.USER_DIR_PREV, site_data_tgt, layout.USER_DIR ) migrate_old_data(site_data_old1, layout.VOCAB_DIR_PREV, site_data_tgt, layout.VOCAB_DIR) # c/_annalist_site/_annalist_collection/ - using new dir names site_data_old2 = os.path.join(sitebasedir, site_layout.SITEDATA_OLD_DIR2) old_users2 = os.path.join(site_data_old2, layout.USER_DIR) old_vocabs2 = os.path.join(site_data_old2, layout.VOCAB_DIR) if os.path.isdir(old_users2) or os.path.isdir(old_vocabs2): print("Copy Annalist old user and/or vocab data from %s"%site_data_old2) migrate_old_data(site_data_old2, layout.USER_DIR_PREV, site_data_tgt, layout.USER_DIR ) migrate_old_data(site_data_old2, layout.VOCAB_DIR_PREV, site_data_tgt, layout.VOCAB_DIR) # --- Archive old site data so it's not visible next time if os.path.isdir(site_data_old1): archive_old_data(site_data_old1, "") if os.path.isdir(site_data_old2): archive_old_data(site_data_old2, "") # --- Copy latest site data to target directory print("Copy Annalist site data") print("from %s"%site_data_src) for sdir in layout.DATA_DIRS: print("- %s -> %s"%(sdir, site_data_tgt)) Site.replace_site_data_dir(sitedata, sdir, site_data_src) for sdir in (layout.USER_DIR, layout.VOCAB_DIR): print("- %s +> %s"%(sdir, site_data_tgt)) Site.update_site_data_dir(sitedata, sdir, site_data_src) for sdir in (layout.INFO_DIR,): print("- %s ~> %s"%(sdir, site_data_tgt)) Site.expand_site_data_dir(sitedata, sdir, site_data_src) for sdir in layout.COLL_DIRS_PREV: remove_old_data(site_data_tgt, sdir) print("Generating context for site data") sitedata.generate_coll_jsonld_context() # --- Copy provider data to site config provider directory provider_dir_src = os.path.join(annroot, "annalist/data/identity_providers") provider_dir_tgt = os.path.join(sitesettings.CONFIG_BASE, "providers") print("Copy identity provider data:") print("- from: %s"%(provider_dir_src,)) print("- to: %s"%(provider_dir_tgt,)) ensure_dir(provider_dir_tgt) updatetree(provider_dir_src, provider_dir_tgt) # --- Copy sample system configuration files to config directory config_dir_src = os.path.join(annroot, "annalist/data/config_examples") config_dir_tgt = os.path.join(sitesettings.CONFIG_BASE, "config") print("Copy system configuration sample files:") print("- from: %s"%(config_dir_src,)) print("- to: %s"%(config_dir_tgt,)) ensure_dir(config_dir_tgt) updatetree(config_dir_src, provider_dir_tgt) return status
class SiteActionViewTests(AnnalistTestCase): """ Tests for Site action views (completion of confirmed actions requested from the site view) """ def setUp(self): init_annalist_test_site() self.testsite = Site(TestBaseUri, TestBaseDir) # self.user = User.objects.create_user('testuser', '*****@*****.**', 'testpassword') # self.user.save() # self.client = Client(HTTP_HOST=TestHost) # Login and permissions create_test_user(None, "testuser", "testpassword") self.client = Client(HTTP_HOST=TestHost) loggedin = self.client.login(username="******", password="******") self.assertTrue(loggedin) create_user_permissions( self.testsite.site_data_collection(), "testuser", user_permissions= [ "VIEW", "CREATE", "UPDATE", "DELETE", "CONFIG" , "CREATE_COLLECTION", "DELETE_COLLECTION" ] ) return def tearDown(self): return @classmethod def setUpClass(cls): # Remove any collections left behind from previous tests resetSitedata(scope="collections") return def _conf_data(self, action="confirm"): action_values = ( { 'confirm': "Confirm" , 'cancel': "Cancel" }) return ( { action: action_values[action] , "confirmed_action": reverse("AnnalistSiteActionView") , "action_params": """{"new_label": [""], "new_id": [""], "select": ["coll1", "coll3"], "remove": ["Remove selected"]}""" , "cancel_action": reverse("AnnalistSiteView") }) def test_SiteActionViewTest(self): self.assertEqual(SiteActionView.__name__, "SiteActionView", "Check SiteActionView class name") return def test_post_confirmed_remove(self): # Submit positive confirmation u = reverse("AnnalistConfirmView") r = self.client.post(u, self._conf_data(action="confirm")) self.assertEqual(r.status_code, 302) self.assertEqual(r.reason_phrase, "FOUND") self.assertEqual(r.content, "") self.assertMatch( r['location'], "^"+TestHostUri+reverse("AnnalistSiteView")+"\\?info_head=.*&info_message=.*coll1,.*coll3.*$" ) # Confirm collections deleted r = self.client.get(TestBasePath+"/site/") colls = r.context['collections'] #@@ (diagnostic only) if len(colls) != len(init_collection_keys)-2: log.warning("@@ Collection count mismatch: %s != %d"%(len(colls), len(init_collection_keys)-2)) log.warning("@@ Collections seen %r"%(colls.keys(),)) #@@ self.assertEqual(len(colls), len(init_collection_keys)-2) id = "coll2" self.assertEqual(colls[id]["annal:id"], id) self.assertEqual(colls[id]["annal:url"], init_collections[id]["annal:url"]) self.assertEqual(colls[id]["rdfs:label"], init_collections[id]["rdfs:label"]) return def test_post_cancelled_remove(self): u = reverse("AnnalistConfirmView") r = self.client.post(u, self._conf_data(action="cancel")) self.assertEqual(r.status_code, 302) self.assertEqual(r.reason_phrase, "FOUND") self.assertEqual(r.content, "") self.assertEqual(r['location'], TestBaseUri+"/site/") # Confirm no collections deleted r = self.client.get(TestBasePath+"/site/") colls = r.context['collections'] self.assertEqual(len(colls), len(init_collection_keys)) for id in init_collections: self.assertEqual(colls[id]["annal:id"], id) self.assertEqual(colls[id]["annal:url"], init_collections[id]["annal:url"]) self.assertEqual(colls[id]["rdfs:label"], init_collections[id]["rdfs:label"]) return
def am_updatesite(annroot, userhome, options): """ Update site data, leaving user data alone annroot is the root directory for the Annalist software installation. userhome is the home directory for the host system user issuing the command. options contains options parsed from the command line. returns 0 if all is well, or a non-zero status code. This value is intended to be used as an exit status code for the calling program. """ status = am_errors.AM_SUCCESS sitesettings = am_get_site_settings(annroot, userhome, options) if not sitesettings: print("Settings not found (%s)" % (options.configuration), file=sys.stderr) return am_errors.AM_NOSETTINGS if len(options.args) > 0: print("Unexpected arguments for %s: (%s)" % (options.command, " ".join(options.args)), file=sys.stderr) return am_errors.AM_UNEXPECTEDARGS site_layout = layout.Layout(sitesettings.BASE_DATA_DIR) sitebasedir = site_layout.SITE_PATH sitebaseurl = "/annalist/" # @@TODO: figure more robust way to define this site = Site(sitebaseurl, site_layout.SITE_PATH) sitedata = site.site_data_collection(test_exists=False) if sitedata is None: print( "Initializing Annalist site metadata in %s (migrating to new layout)" % (sitebasedir)) site = Site.create_empty_site_data( sitebaseurl, sitebasedir, label="Annalist site (%s configuration)" % options.configuration, description="Annalist %s site metadata and site-wide values." % options.configuration) sitedata = site.site_data_collection() site_data_src = os.path.join( annroot, "annalist/data/sitedata") # @@TODO: more robust definition site_data_tgt, site_data_file = sitedata._dir_path() # --- Migrate old site data to new site directory site_data_old = os.path.join(sitebasedir, site_layout.SITEDATA_OLD_DIR) old_users = os.path.join(site_data_old, layout.USER_DIR_PREV) old_vocabs = os.path.join(site_data_old, layout.VOCAB_DIR_PREV) if os.path.isdir(old_users) or os.path.isdir(old_vocabs): print("Copy Annalist old user and/or vocab data from %s" % site_data_old) migrate_old_data(site_data_old, layout.USER_DIR_PREV, site_data_tgt, layout.USER_DIR) migrate_old_data(site_data_old, layout.VOCAB_DIR_PREV, site_data_tgt, layout.VOCAB_DIR) #@@ # if os.path.isdir(old_users) or os.path.isdir(old_vocabs): # print("Copy Annalist old user and/or vocab data from %s"%site_data_old) # for sdir in ("users", "vocabs"): # s = os.path.join(site_data_old, sdir) # old_s = os.path.join(site_data_old, "old_"+sdir) # d = os.path.join(site_data_tgt, sdir) # if os.path.isdir(s): # print("- %s +> %s (migrating)"%(sdir, d)) # updatetree(s, d) # print("- %s >> %s (rename)"%(sdir, old_s)) # os.rename(s, old_s) #@@ # --- Copy latest site data to target directory print("Copy Annalist site data") print("from %s" % site_data_src) for sdir in layout.DATA_DIRS: print("- %s -> %s" % (sdir, site_data_tgt)) Site.replace_site_data_dir(sitedata, sdir, site_data_src) for sdir in (layout.USER_DIR, layout.VOCAB_DIR): print("- %s +> %s" % (sdir, site_data_tgt)) Site.update_site_data_dir(sitedata, sdir, site_data_src) for sdir in layout.COLL_DIRS_PREV: remove_old_data(site_data_tgt, sdir) print("Generating %s" % (site_layout.SITEDATA_CONTEXT_DIR)) sitedata.generate_coll_jsonld_context() # --- Copy provider data to site config provider directory provider_dir_tgt = os.path.join(sitesettings.CONFIG_BASE, "providers") provider_dir_src = os.path.join(annroot, "annalist/data/identity_providers") print("Copy identity provider data:") print("- from: %s" % (provider_dir_src, )) print("- to: %s" % (provider_dir_tgt, )) updatetree(provider_dir_src, provider_dir_tgt) return status
class CollectionDataEditViewTest(AnnalistTestCase): """ Tests for collection data edit view """ def setUp(self): init_annalist_test_site() self.testsite = Site(TestBaseUri, TestBaseDir) self.testcoll = Collection.create(self.testsite, "testcoll", collection_create_values("testcoll")) # Login and permissions create_test_user( self.testsite.site_data_collection(), # self.testcoll, "testuser", "testpassword", user_permissions=["VIEW", "CREATE", "UPDATE", "DELETE", "CONFIG", "ADMIN"] ) self.client = Client(HTTP_HOST=TestHost) loggedin = self.client.login(username="******", password="******") self.assertTrue(loggedin) return def tearDown(self): resetSitedata() return # ----------------------------------------------------------------------------- # Helpers # ----------------------------------------------------------------------------- def _check_collection_data_values(self, coll_id=None): """ Helper function checks content of annalist collection data """ self.assertTrue(Collection.exists(self.testsite, coll_id)) t = Collection.load(self.testsite, coll_id) self.assertEqual(t.get_id(), coll_id) self.assertEqual(t.get_view_url_path(), collection_view_url(coll_id="testcoll")) v = collectiondata_values(coll_id=coll_id) self.assertDictionaryMatch(t.get_values(), v) return t # ----------------------------------------------------------------------------- # Form rendering and access tests # ----------------------------------------------------------------------------- def test_get_collection_data_form_rendering(self): u = entitydata_edit_url("new", "_annalist_site", "_coll", view_id="Collection_view") r = self.client.get(u) self.assertEqual(r.status_code, 200) self.assertEqual(r.reason_phrase, "OK") field_vals = default_fields( coll_id="_annalist_site", type_id="_coll", entity_id="00000001", sotware_ver=annalist.__version_data__, tooltip1a=context_view_field(r.context, 0, 0)['field_help'], tooltip1b=context_view_field(r.context, 0, 1)['field_help'], tooltip2 =context_view_field(r.context, 1, 0)['field_help'], tooltip3 =context_view_field(r.context, 2, 0)['field_help'], tooltip4 =context_view_field(r.context, 3, 0)['field_help'], tooltip5a=context_view_field(r.context, 4, 0)['field_help'], tooltip5b=context_view_field(r.context, 4, 1)['field_help'], tooltip6a=context_view_field(r.context, 5, 0)['field_help'], tooltip6b=context_view_field(r.context, 5, 1)['field_help'], tooltip7 =context_view_field(r.context, 6, 0)['field_help'], ) formrow1a = """ <div class="small-12 medium-6 columns" title="%(tooltip1a)s"> <div class="row view-value-row"> <div class="%(label_classes)s"> <span>Id</span> </div> <div class="%(input_classes)s"> <input type="text" size="64" name="entity_id" placeholder="(entity id)" value="00000001" /> </div> </div> </div> """%field_vals(width=6) formrow1b = """ <div class="small-12 medium-6 columns" title="%(tooltip1b)s"> <div class="row view-value-row"> <div class="%(label_classes)s"> <span>S/W version</span> </div> <div class="%(input_classes)s"> <span> </span> </div> </div> </div> """%field_vals(width=6) formrow2 = """ <div class="small-12 columns" title="%(tooltip2)s"> <div class="row view-value-row"> <div class="%(label_classes)s"> <span>Label</span> </div> <div class="%(input_classes)s"> <input type="text" size="64" name="Entity_label" placeholder="(label)" value="" /> </div> </div> </div> """%field_vals(width=12) formrow3 = """ <div class="small-12 columns" title="%(tooltip3)s"> <div class="row view-value-row"> <div class="%(label_classes)s"> <span>Comment</span> </div> <div class="%(input_classes)s"> <textarea cols="64" rows="6" name="Entity_comment" class="small-rows-4 medium-rows-8" placeholder="(description)" > </textarea> </div> </div> </div> """%field_vals(width=12) formrow4 = """ <div class="small-12 columns" title="%(tooltip4)s"> <div class="row view-value-row"> <div class="%(label_classes)s"> <span>Parent</span> </div> <div class="%(input_classes)s"> <select name="Coll_parent"> <option value="" selected="selected">(site)</option> <option value="_coll/_annalist_site">Annalist data notebook test site</option> <option value="_coll/coll1">Collection coll1</option> <option value="_coll/coll2">Collection coll2</option> <option value="_coll/coll3">Collection coll3</option> <option value="_coll/testcoll">Collection testcoll</option> </select> </div> </div> </div> """%field_vals(width=12) formrow5a = """ <div class="small-12 medium-6 columns" title="%(tooltip5a)s"> <div class="row view-value-row"> <div class="%(label_classes)s"> <span>Default list</span> </div> <div class="%(input_classes)s"> <span> </span> </div> </div> </div> """%field_vals(width=6) formrow5b = """ <div class="small-12 medium-6 columns" title="%(tooltip5b)s"> <div class="row view-value-row"> <div class="%(label_classes)s"> <span>Default view</span> </div> <div class="%(input_classes)s"> <span> </span> </div> </div> </div> """%field_vals(width=6) formrow6a = """ <div class="small-12 medium-6 columns" title="%(tooltip6a)s"> <div class="row view-value-row"> <div class="%(label_classes)s"> <span>Default view type</span> </div> <div class="%(input_classes)s"> <span> </span> </div> </div> </div> """%field_vals(width=6) formrow6b = """ <div class="small-12 medium-6 columns" title="%(tooltip6b)s"> <div class="row view-value-row"> <div class="%(label_classes)s"> <span>Default view entity</span> </div> <div class="%(input_classes)s"> <span> </span> </div> </div> </div> """%field_vals(width=6) formrow7 = """ <div class="small-12 columns" title="%(tooltip7)s"> <div class="row view-value-row"> <div class="%(label_classes)s"> <span>Collection metadata</span> </div> <div class="%(input_classes)s"> <textarea cols="64" rows="6" name="Coll_comment" class="small-rows-4 medium-rows-8" placeholder="(annal:meta_comment)" > </textarea> </div> </div> </div> """%field_vals(width=12) # log.info(r.content) self.assertContains(r, formrow1a, html=True) self.assertContains(r, formrow1b, html=True) self.assertContains(r, formrow2, html=True) self.assertContains(r, formrow3, html=True) self.assertContains(r, formrow4, html=True) self.assertContains(r, formrow5a, html=True) self.assertContains(r, formrow5b, html=True) self.assertContains(r, formrow6a, html=True) self.assertContains(r, formrow6b, html=True) self.assertContains(r, formrow7, html=True) return # collection default view def test_get_default_view(self): u = collectiondata_url(coll_id="testcoll") r = self.client.get(u) self.assertEqual(r.status_code, 200) self.assertEqual(r.reason_phrase, "OK") self.assertEqual(r.context['coll_id'], "_annalist_site") self.assertEqual(r.context['type_id'], "_coll") self.assertEqual(r.context['entity_id'], "testcoll") self.assertEqual(r.context['orig_id'], "testcoll") self.assertEqual(r.context['action'], "view") self.assertEqual(r.context['continuation_url'], "") return # collection default view metadata access def test_get_default_view_metadata(self): u = collectiondata_resource_url(coll_id="testcoll") r = self.client.get(u) self.assertEqual(r.status_code, 200) self.assertEqual(r.reason_phrase, "OK") colldata = json.loads(r.content) expected = ( { "@id": "../" , "@type": [ "annal:Collection" ] , "@context": [ {"@base": "../d/"}, "coll_context.jsonld" ] , "annal:id": "testcoll" , "annal:type_id": "_coll" , "annal:type": "annal:Collection" , "rdfs:label": "Collection testcoll" , "rdfs:comment": "Description of Collection testcoll" , "annal:software_version": annalist.__version_data__ }) self.assertEqual(colldata, expected) return # collection named view context def test_get_named_view(self): u = collectiondata_view_url(coll_id="testcoll", action="view") r = self.client.get(u) self.assertEqual(r.status_code, 200) self.assertEqual(r.reason_phrase, "OK") self.assertEqual(r.context['coll_id'], "_annalist_site") self.assertEqual(r.context['type_id'], "_coll") self.assertEqual(r.context['entity_id'], "testcoll") self.assertEqual(r.context['orig_id'], "testcoll") self.assertEqual(r.context['action'], "view") self.assertEqual(r.context['continuation_url'], "") return # collection named view edit def test_get_named_edit(self): u = collectiondata_view_url(coll_id="testcoll", action="edit") r = self.client.get(u) self.assertEqual(r.status_code, 200) self.assertEqual(r.reason_phrase, "OK") self.assertEqual(r.context['coll_id'], "_annalist_site") self.assertEqual(r.context['type_id'], "_coll") self.assertEqual(r.context['entity_id'], "testcoll") self.assertEqual(r.context['orig_id'], "testcoll") self.assertEqual(r.context['action'], "edit") self.assertEqual(r.context['continuation_url'], "") return # collection named view edit post update def test_post_named_edit(self): u = collectiondata_view_url(coll_id="testcoll", action="edit") f = collectiondata_view_form_data(coll_id="testcoll", action="edit") r = self.client.post(u, f) self.assertEqual(r.status_code, 302) self.assertEqual(r.reason_phrase, "FOUND") self.assertEqual(r.content, "") self.assertEqual(r['location'], TestBaseUri+"/c/_annalist_site/d/_coll/") # Check updated collection data self._check_collection_data_values(coll_id="testcoll") return # collection named view metadata access def test_get_named_view_metadata(self): u = collectiondata_view_resource_url(coll_id="testcoll") r = self.client.get(u) self.assertEqual(r.status_code, 200) self.assertEqual(r.reason_phrase, "OK") colldata = json.loads(r.content) expected = ( { "@id": "../" , "@type": [ "annal:Collection" ] , "@context": [ {"@base": "../d/"}, "coll_context.jsonld" ] , "annal:id": "testcoll" , "annal:type_id": "_coll" , "annal:type": "annal:Collection" , "rdfs:label": "Collection testcoll" , "rdfs:comment": "Description of Collection testcoll" , "annal:software_version": annalist.__version_data__ }) self.assertEqual(colldata, expected) return # ----------------------------------------------------------------------------- # Form response tests # ----------------------------------------------------------------------------- def _no_test_post_copy_coll(self): # The main purpose of this test is to check that user permissions are saved properly self.assertFalse(CollectionData.exists(self.testcoll, "copyuser")) f = annalistuser_view_form_data( action="copy", orig_id="_default_coll_perms", user_id="copyuser", user_name="User copyuser", user_uri="mailto:[email protected]", user_permissions="VIEW CREATE UPDATE DELETE" ) u = entitydata_edit_url( "copy", "testcoll", "_coll", entity_id="_default_coll_perms", view_id="User_view" ) r = self.client.post(u, f) self.assertEqual(r.status_code, 302) self.assertEqual(r.reason_phrase, "FOUND") self.assertEqual(r.content, "") self.assertEqual(r['location'], self.continuation_url) # Check that new record type exists self.assertTrue(CollectionData.exists(self.testcoll, "copyuser")) self._check_annalist_coll_values("copyuser", ["VIEW", "CREATE", "UPDATE", "DELETE"]) return
class SiteViewTest(AnnalistTestCase): """ Tests for Site views """ def setUp(self): init_annalist_test_site() self.testsite = Site(TestBaseUri, TestBaseDir) self.uri = reverse("AnnalistSiteView") self.homeuri = reverse("AnnalistHomeView") self.profileuri = reverse("AnnalistProfileView") # Login and permissions create_test_user(None, "testuser", "testpassword") self.client = Client(HTTP_HOST=TestHost) loggedin = self.client.login(username="******", password="******") self.assertTrue(loggedin) create_user_permissions( self.testsite.site_data_collection(), "testuser", user_permissions= [ "VIEW", "CREATE", "UPDATE", "DELETE", "CONFIG" , "CREATE_COLLECTION", "DELETE_COLLECTION" ] ) return def tearDown(self): return @classmethod def tearDownClass(cls): resetSitedata(scope="all") return def test_SiteViewTest(self): self.assertEqual(SiteView.__name__, "SiteView", "Check SiteView class name") return def test_get(self): # @@TODO: use reference to self.client, per # https://docs.djangoproject.com/en/dev/topics/testing/tools/#default-test-client r = self.client.get(self.uri) self.assertEqual(r.status_code, 200) self.assertEqual(r.reason_phrase, "OK") self.assertContains(r, site_title("<title>%s</title>")) return def test_get_error(self): r = self.client.get(self.uri+"?error_head=Error&error_message=Error%20presented") self.assertEqual(r.status_code, 200) self.assertEqual(r.reason_phrase, "OK") # self.assertEqual(r.content, "???") self.assertContains(r, """<h3>Error</h3>""", html=True) self.assertContains(r, """<p class="messages">Error presented</p>""", html=True) return def test_get_info(self): r = self.client.get(self.uri+"?info_head=Information&info_message=Information%20presented") self.assertEqual(r.status_code, 200) self.assertEqual(r.reason_phrase, "OK") self.assertContains(r, """<h3>Information</h3>""", html=True) self.assertContains(r, """<p class="messages">Information presented</p>""", html=True) return def test_get_home(self): r = self.client.get(self.homeuri) self.assertEqual(r.status_code, 302) self.assertEqual(r.reason_phrase, "FOUND") self.assertEqual(r["location"], TestHostUri+self.uri) return def test_get_no_login(self): self.client.logout() r = self.client.get(self.uri) self.assertFalse(r.context["auth_create"]) self.assertFalse(r.context["auth_update"]) self.assertFalse(r.context["auth_delete"]) colls = r.context['collections'] self.assertEqual(len(colls), len(init_collection_keys)) for id in init_collections: self.assertEqual(colls[id]["annal:id"], id) self.assertEqual(colls[id]["annal:url"], init_collections[id]["annal:url"]) self.assertEqual(colls[id]["rdfs:label"], init_collections[id]["rdfs:label"]) # Check returned HTML (checks template logic) # (Don't need to keep doing this as logic can be tested through context as above) # (See: http://stackoverflow.com/questions/2257958/) s = BeautifulSoup(r.content, "html.parser") self.assertEqual(s.html.title.string, site_title()) homelink = s.find(class_="title-area").find(class_="name").h1.a self.assertEqual(homelink.string, "Home") self.assertEqual(homelink['href'], self.uri) menuitems = s.find(class_="top-bar-section").find(class_="right").find_all("li") self.assertEqualIgnoreWS(menuitems[0].a.string, "Login") self.assertEqual(menuitems[0].a['href'], self.profileuri) # Check displayed collections trows = s.form.find_all("div", class_="tbody") self.assertEqual(len(trows), len(init_collection_keys)) self.assertEqual(trows[0].div.div('div')[1].a.string, "_annalist_site") self.assertEqual(trows[0].div.div('div')[1].a['href'], collection_view_url("_annalist_site")) self.assertEqual(trows[1].div.div('div')[1].a.string, "coll1") self.assertEqual(trows[1].div.div('div')[1].a['href'], collection_view_url("coll1")) self.assertEqual(trows[2].div.div('div')[1].a.string, "coll2") self.assertEqual(trows[2].div.div('div')[1].a['href'], collection_view_url("coll2")) self.assertEqual(trows[3].div.div('div')[1].a.string, "coll3") self.assertEqual(trows[3].div.div('div')[1].a['href'], collection_view_url("coll3")) return def test_get_with_login(self): r = self.client.get(self.uri) # Preferred way to test main view logic self.assertTrue(r.context["auth_create"]) self.assertTrue(r.context["auth_update"]) self.assertTrue(r.context["auth_delete"]) self.assertTrue(r.context["auth_create_coll"]) self.assertTrue(r.context["auth_delete_coll"]) colls = r.context['collections'] self.assertEqual(len(colls), len(init_collection_keys)) for id in init_collections: # First two here added in models.site.site_data() self.assertEqual(colls[id]["id"], id) self.assertEqual(colls[id]["url"], init_collections[id]["annal:url"]) self.assertEqual(colls[id]["annal:id"], id) self.assertEqual(colls[id]["annal:url"], init_collections[id]["annal:url"]) self.assertEqual(colls[id]["rdfs:label"], init_collections[id]["rdfs:label"]) # Check returned HTML (checks template logic) # (Don't need to keep doing this as logic can be tested through context as above) # (See: http://stackoverflow.com/questions/2257958/) s = BeautifulSoup(r.content, "html.parser") # title and top menu self.assertEqual(s.html.title.string, site_title()) homelink = s.find(class_="title-area").find(class_="name").h1.a self.assertEqual(homelink.string, "Home") self.assertEqual(homelink['href'], self.uri) menuitems = s.find(class_="top-bar-section").find(class_="right").find_all("li") self.assertEqualIgnoreWS(menuitems[0].a.string, "User testuser") self.assertEqual(menuitems[0].a['href'], TestBasePath+"/profile/") self.assertEqualIgnoreWS(menuitems[1].a.string, "Logout") self.assertEqual(menuitems[1].a['href'], TestBasePath+"/logout/") # Displayed colllections and check-buttons # trows = s.form.find_all("div", class_="tbody") trows = s.select("form > div > div > div") self.assertEqual(len(trows), len(init_collection_keys)+4) site_data = ( [ (1, "checkbox", "select", "_annalist_site") , (2, "checkbox", "select", "coll1") , (3, "checkbox", "select", "coll2") , (4, "checkbox", "select", "coll3") ]) for i, itype, iname, ivalue in site_data: # tcols = trows[i].find_all("div", class_="view-value") tcols = trows[i].select("div > div > div") self.assertEqual(tcols[0].input['type'], itype) self.assertEqual(tcols[0].input['name'], iname) self.assertEqual(tcols[0].input['value'], ivalue) self.assertEqual(tcols[1].a.string, ivalue) self.assertEqual(tcols[1].a['href'], collection_view_url(ivalue)) # buttons to view/edit/remove selected btn_view = trows[5].select("div > input")[0] self.assertEqual(btn_view["type"], "submit") self.assertEqual(btn_view["name"], "view") btn_edit = trows[5].select("div > input")[1] self.assertEqual(btn_edit["type"], "submit") self.assertEqual(btn_edit["name"], "edit") btn_remove = trows[5].select("div > input")[2] self.assertEqual(btn_remove["type"], "submit") self.assertEqual(btn_remove["name"], "remove") # Input fields for new collection add_fields = trows[6].select("div > div > div") field_id = add_fields[1].input field_label = add_fields[2].input self.assertEqual(field_id["type"], "text") self.assertEqual(field_id["name"], "new_id") self.assertEqual(field_label["type"], "text") self.assertEqual(field_label["name"], "new_label") # Button for new collection btn_new = trows[7].select("div > input")[0] self.assertEqual(btn_new["type"], "submit") self.assertEqual(btn_new["name"], "new") return def test_post_add(self): form_data = collection_new_form_data("testnew") r = self.client.post(self.uri, form_data) self.assertEqual(r.status_code, 302) self.assertEqual(r.reason_phrase, "FOUND") self.assertEqual(r.content, "") self.assertEqual(r['location'], TestBaseUri+"/site/" "?info_head=Action%20completed"+ "&info_message=Created%20new%20collection:%20'testnew'") # Check site now has new colllection r = self.client.get(self.uri) new_collections = init_collections.copy() new_collections["testnew"] = collection_values("testnew", hosturi=TestHostUri) colls = r.context['collections'] for id in new_collections: p = "[%s]"%id # First two here added in model.site.site_data for view template self.assertEqualPrefix(colls[id]["id"], id, p) self.assertEqualPrefix(colls[id]["url"], new_collections[id]["annal:url"], p) self.assertEqualPrefix(colls[id]["annal:id"], id, p) self.assertEqualPrefix(colls[id]["annal:url"], new_collections[id]["annal:url"], p) self.assertEqualPrefix(colls[id]["rdfs:label"], new_collections[id]["rdfs:label"], p) # Check new collection has admin permissions for creator new_coll = Collection(self.testsite, "testnew") testuser_perms = new_coll.get_user_permissions("testuser", "mailto:testuser@%s"%TestHost) expect_perms = ["VIEW", "CREATE", "UPDATE", "DELETE", "CONFIG", "ADMIN"] expect_descr = "User testuser: permissions for Test User in collection testnew" self.assertEqual(testuser_perms[ANNAL.CURIE.id], "testuser") self.assertEqual(testuser_perms[RDFS.CURIE.label], "Test User") self.assertEqual(testuser_perms[RDFS.CURIE.comment], expect_descr) self.assertEqual(testuser_perms[ANNAL.CURIE.user_uri], "mailto:testuser@%s"%TestHost) self.assertEqual(testuser_perms[ANNAL.CURIE.user_permission], expect_perms) return def test_post_remove(self): form_data = collection_remove_form_data(["coll1", "coll3"]) r = self.client.post(self.uri, form_data) self.assertEqual(r.status_code, 200) self.assertEqual(r.reason_phrase, "OK") self.assertTemplateUsed(r, "annalist_confirm.html") # Returns confirmation form: check self.assertContains(r, '''<form method="POST" action="'''+TestBasePath+'''/confirm/">''', status_code=200) self.assertContains(r, '''<input type="submit" name="confirm" value="Confirm"/>''', html=True) self.assertContains(r, '''<input type="submit" name="cancel" value="Cancel"/>''', html=True) self.assertContains(r, '''<input type="hidden" name="confirmed_action" value="'''+reverse("AnnalistSiteActionView")+'''"/>''', html=True) self.assertContains(r, '''<input type="hidden" name="action_params" value="{"new_label": [""], "new_id": [""], "select": ["coll1", "coll3"], "remove": ["Remove selected"]}"/>''', html=True) self.assertContains(r, '''<input type="hidden" name="cancel_action" value="'''+reverse("AnnalistSiteView")+'''"/>''', html=True) return
class CollectionDataEditViewTest(AnnalistTestCase): """ Tests for collection data edit view """ def setUp(self): init_annalist_test_site() self.testsite = Site(TestBaseUri, TestBaseDir) self.testcoll = Collection.create(self.testsite, "testcoll", collection_create_values("testcoll")) # Login and permissions create_test_user( self.testsite.site_data_collection(), # self.testcoll, "testuser", "testpassword", user_permissions=[ "VIEW", "CREATE", "UPDATE", "DELETE", "CONFIG", "ADMIN" ]) self.client = Client(HTTP_HOST=TestHost) loggedin = self.client.login(username="******", password="******") self.assertTrue(loggedin) return def tearDown(self): resetSitedata() return # ----------------------------------------------------------------------------- # Helpers # ----------------------------------------------------------------------------- def _check_collection_data_values(self, coll_id=None): """ Helper function checks content of annalist collection data """ self.assertTrue(Collection.exists(self.testsite, coll_id)) t = Collection.load(self.testsite, coll_id) self.assertEqual(t.get_id(), coll_id) self.assertEqual(t.get_view_url_path(), collection_view_url(coll_id="testcoll")) v = collectiondata_values(coll_id=coll_id) self.assertDictionaryMatch(t.get_values(), v) return t # ----------------------------------------------------------------------------- # Form rendering and access tests # ----------------------------------------------------------------------------- def test_get_collection_data_form_rendering(self): u = entitydata_edit_url("new", "_annalist_site", "_coll", view_id="Collection_view") r = self.client.get(u) self.assertEqual(r.status_code, 200) self.assertEqual(r.reason_phrase, "OK") field_vals = default_fields( coll_id="_annalist_site", type_id="_coll", entity_id="00000001", sotware_ver=annalist.__version_data__, tooltip1a=context_view_field(r.context, 0, 0)['field_help'], tooltip1b=context_view_field(r.context, 0, 1)['field_help'], tooltip2=context_view_field(r.context, 1, 0)['field_help'], tooltip3=context_view_field(r.context, 2, 0)['field_help'], tooltip4=context_view_field(r.context, 3, 0)['field_help'], tooltip5a=context_view_field(r.context, 4, 0)['field_help'], tooltip5b=context_view_field(r.context, 4, 1)['field_help'], tooltip6a=context_view_field(r.context, 5, 0)['field_help'], tooltip6b=context_view_field(r.context, 5, 1)['field_help'], tooltip7=context_view_field(r.context, 6, 0)['field_help'], ) formrow1a = """ <div class="small-12 medium-6 columns" title="%(tooltip1a)s"> <div class="row view-value-row"> <div class="%(label_classes)s"> <span>Id</span> </div> <div class="%(input_classes)s"> <input type="text" size="64" name="entity_id" placeholder="(entity id)" value="00000001" /> </div> </div> </div> """ % field_vals(width=6) formrow1b = """ <div class="small-12 medium-6 columns" title="%(tooltip1b)s"> <div class="row view-value-row"> <div class="%(label_classes)s"> <span>S/W version</span> </div> <div class="%(input_classes)s"> <span> </span> </div> </div> </div> """ % field_vals(width=6) formrow2 = """ <div class="small-12 columns" title="%(tooltip2)s"> <div class="row view-value-row"> <div class="%(label_classes)s"> <span>Label</span> </div> <div class="%(input_classes)s"> <input type="text" size="64" name="Entity_label" placeholder="(label)" value="" /> </div> </div> </div> """ % field_vals(width=12) formrow3 = """ <div class="small-12 columns" title="%(tooltip3)s"> <div class="row view-value-row"> <div class="%(label_classes)s"> <span>Comment</span> </div> <div class="%(input_classes)s"> <textarea cols="64" rows="6" name="Entity_comment" class="small-rows-4 medium-rows-8" placeholder="(description)" > </textarea> </div> </div> </div> """ % field_vals(width=12) formrow4 = """ <div class="small-12 columns" title="%(tooltip4)s"> <div class="row view-value-row"> <div class="%(label_classes)s"> <span>Parent</span> </div> <div class="%(input_classes)s"> <select name="Coll_parent"> <option value="" selected="selected">(site)</option> <option value="_coll/_annalist_site">Annalist data notebook test site</option> <option value="_coll/coll1">Collection coll1</option> <option value="_coll/coll2">Collection coll2</option> <option value="_coll/coll3">Collection coll3</option> <option value="_coll/testcoll">Collection testcoll</option> </select> </div> </div> </div> """ % field_vals(width=12) formrow5a = """ <div class="small-12 medium-6 columns" title="%(tooltip5a)s"> <div class="row view-value-row"> <div class="%(label_classes)s"> <span>Default list</span> </div> <div class="%(input_classes)s"> <span> </span> </div> </div> </div> """ % field_vals(width=6) formrow5b = """ <div class="small-12 medium-6 columns" title="%(tooltip5b)s"> <div class="row view-value-row"> <div class="%(label_classes)s"> <span>Default view</span> </div> <div class="%(input_classes)s"> <span> </span> </div> </div> </div> """ % field_vals(width=6) formrow6a = """ <div class="small-12 medium-6 columns" title="%(tooltip6a)s"> <div class="row view-value-row"> <div class="%(label_classes)s"> <span>Default view type</span> </div> <div class="%(input_classes)s"> <span> </span> </div> </div> </div> """ % field_vals(width=6) formrow6b = """ <div class="small-12 medium-6 columns" title="%(tooltip6b)s"> <div class="row view-value-row"> <div class="%(label_classes)s"> <span>Default view entity</span> </div> <div class="%(input_classes)s"> <span> </span> </div> </div> </div> """ % field_vals(width=6) formrow7 = """ <div class="small-12 columns" title="%(tooltip7)s"> <div class="row view-value-row"> <div class="%(label_classes)s"> <span>Collection metadata</span> </div> <div class="%(input_classes)s"> <textarea cols="64" rows="6" name="Coll_comment" class="small-rows-4 medium-rows-8" placeholder="(annal:meta_comment)" > </textarea> </div> </div> </div> """ % field_vals(width=12) # log.info(r.content) self.assertContains(r, formrow1a, html=True) self.assertContains(r, formrow1b, html=True) self.assertContains(r, formrow2, html=True) self.assertContains(r, formrow3, html=True) self.assertContains(r, formrow4, html=True) self.assertContains(r, formrow5a, html=True) self.assertContains(r, formrow5b, html=True) self.assertContains(r, formrow6a, html=True) self.assertContains(r, formrow6b, html=True) self.assertContains(r, formrow7, html=True) return # collection default view def test_get_default_view(self): u = collectiondata_url(coll_id="testcoll") r = self.client.get(u) self.assertEqual(r.status_code, 200) self.assertEqual(r.reason_phrase, "OK") self.assertEqual(r.context['coll_id'], "_annalist_site") self.assertEqual(r.context['type_id'], "_coll") self.assertEqual(r.context['entity_id'], "testcoll") self.assertEqual(r.context['orig_id'], "testcoll") self.assertEqual(r.context['action'], "view") self.assertEqual(r.context['continuation_url'], "") return # collection default view metadata access def test_get_default_view_metadata(self): u = collectiondata_resource_url(coll_id="testcoll") r = self.client.get(u) self.assertEqual(r.status_code, 200) self.assertEqual(r.reason_phrase, "OK") colldata = json.loads(r.content) expected = ({ "@id": "../", "@type": ["annal:Collection"], "@context": [{ "@base": "../d/" }, "coll_context.jsonld"], "annal:id": "testcoll", "annal:type_id": "_coll", "annal:type": "annal:Collection", "rdfs:label": "Collection testcoll", "rdfs:comment": "Description of Collection testcoll", "annal:software_version": annalist.__version_data__ }) self.assertEqual(colldata, expected) return # collection named view context def test_get_named_view(self): u = collectiondata_view_url(coll_id="testcoll", action="view") r = self.client.get(u) self.assertEqual(r.status_code, 200) self.assertEqual(r.reason_phrase, "OK") self.assertEqual(r.context['coll_id'], "_annalist_site") self.assertEqual(r.context['type_id'], "_coll") self.assertEqual(r.context['entity_id'], "testcoll") self.assertEqual(r.context['orig_id'], "testcoll") self.assertEqual(r.context['action'], "view") self.assertEqual(r.context['continuation_url'], "") return # collection named view edit def test_get_named_edit(self): u = collectiondata_view_url(coll_id="testcoll", action="edit") r = self.client.get(u) self.assertEqual(r.status_code, 200) self.assertEqual(r.reason_phrase, "OK") self.assertEqual(r.context['coll_id'], "_annalist_site") self.assertEqual(r.context['type_id'], "_coll") self.assertEqual(r.context['entity_id'], "testcoll") self.assertEqual(r.context['orig_id'], "testcoll") self.assertEqual(r.context['action'], "edit") self.assertEqual(r.context['continuation_url'], "") return # collection named view edit post update def test_post_named_edit(self): u = collectiondata_view_url(coll_id="testcoll", action="edit") f = collectiondata_view_form_data(coll_id="testcoll", action="edit") r = self.client.post(u, f) self.assertEqual(r.status_code, 302) self.assertEqual(r.reason_phrase, "FOUND") self.assertEqual(r.content, "") self.assertEqual(r['location'], TestBaseUri + "/c/_annalist_site/d/_coll/") # Check updated collection data self._check_collection_data_values(coll_id="testcoll") return # collection named view metadata access def test_get_named_view_metadata(self): u = collectiondata_view_resource_url(coll_id="testcoll") r = self.client.get(u) self.assertEqual(r.status_code, 200) self.assertEqual(r.reason_phrase, "OK") colldata = json.loads(r.content) expected = ({ "@id": "../", "@type": ["annal:Collection"], "@context": [{ "@base": "../d/" }, "coll_context.jsonld"], "annal:id": "testcoll", "annal:type_id": "_coll", "annal:type": "annal:Collection", "rdfs:label": "Collection testcoll", "rdfs:comment": "Description of Collection testcoll", "annal:software_version": annalist.__version_data__ }) self.assertEqual(colldata, expected) return # ----------------------------------------------------------------------------- # Form response tests # ----------------------------------------------------------------------------- def _no_test_post_copy_coll(self): # The main purpose of this test is to check that user permissions are saved properly self.assertFalse(CollectionData.exists(self.testcoll, "copyuser")) f = annalistuser_view_form_data( action="copy", orig_id="_default_coll_perms", user_id="copyuser", user_name="User copyuser", user_uri="mailto:[email protected]", user_permissions="VIEW CREATE UPDATE DELETE") u = entitydata_edit_url("copy", "testcoll", "_coll", entity_id="_default_coll_perms", view_id="User_view") r = self.client.post(u, f) self.assertEqual(r.status_code, 302) self.assertEqual(r.reason_phrase, "FOUND") self.assertEqual(r.content, "") self.assertEqual(r['location'], self.continuation_url) # Check that new record type exists self.assertTrue(CollectionData.exists(self.testcoll, "copyuser")) self._check_annalist_coll_values( "copyuser", ["VIEW", "CREATE", "UPDATE", "DELETE"]) return
class CollectionDataEditViewTest(AnnalistTestCase): """ Tests for collection data edit view """ def setUp(self): init_annalist_test_site() self.testsite = Site(TestBaseUri, TestBaseDir) self.testcoll = Collection.create(self.testsite, "testcoll", collection_create_values("testcoll")) # Login and permissions create_test_user( self.testsite.site_data_collection(), # self.testcoll, "testuser", "testpassword", user_permissions=["VIEW", "CREATE", "UPDATE", "DELETE", "CONFIG", "ADMIN"] ) self.client = Client(HTTP_HOST=TestHost) loggedin = self.client.login(username="******", password="******") self.assertTrue(loggedin) return def tearDown(self): resetSitedata(scope="all") return # ----------------------------------------------------------------------------- # Helpers # ----------------------------------------------------------------------------- def _check_collection_data_values(self, coll_id=None, coll_label=None, coll_descr=None): """ Helper function checks content of annalist collection data """ self.assertTrue(Collection.exists(self.testsite, coll_id)) c = Collection.load(self.testsite, coll_id) self.assertEqual(c.get_id(), coll_id) self.assertEqual(c.get_view_url_path(), collection_view_url(coll_id="testcoll")) v = collectiondata_values( coll_id=coll_id, coll_label=coll_label, coll_descr=coll_descr ) self.assertDictionaryMatch(c.get_values(), v) return c def _check_annalist_user_perms(self, user_id, user_perms): self.assertTrue(AnnalistUser.exists(self.testcoll, user_id)) u = AnnalistUser.load(self.testcoll, user_id) self.assertEqual(u.get_id(), user_id) self.assertEqual(u[ANNAL.CURIE.user_permission], user_perms) return # ----------------------------------------------------------------------------- # Form rendering and access tests # ----------------------------------------------------------------------------- def test_get_collection_data_form_rendering(self): u = entitydata_edit_url("new", layout.SITEDATA_ID, layout.COLL_TYPEID, view_id="Collection_view") r = self.client.get(u) self.assertEqual(r.status_code, 200) self.assertEqual(r.reason_phrase, "OK") field_vals = default_fields( coll_id=layout.SITEDATA_ID, type_id=layout.COLL_TYPEID, entity_id="00000001", sotware_ver=annalist.__version_data__, tooltip1a=context_view_field(r.context, 0, 0)['field_tooltip'], tooltip1b=context_view_field(r.context, 0, 1)['field_tooltip'], tooltip2 =context_view_field(r.context, 1, 0)['field_tooltip'], tooltip3 =context_view_field(r.context, 2, 0)['field_tooltip'], tooltip4 =context_view_field(r.context, 3, 0)['field_tooltip'], tooltip5a=context_view_field(r.context, 4, 0)['field_tooltip'], tooltip5b=context_view_field(r.context, 4, 1)['field_tooltip'], tooltip6a=context_view_field(r.context, 5, 0)['field_tooltip'], tooltip6b=context_view_field(r.context, 5, 1)['field_tooltip'], tooltip7 =context_view_field(r.context, 6, 0)['field_tooltip'], ) formrow1a = """ <div class="small-12 medium-6 columns" title="%(tooltip1a)s"> <div class="row view-value-row"> <div class="%(label_classes)s"> <span>Id</span> </div> <div class="%(input_classes)s"> <input type="text" size="64" name="entity_id" placeholder="(entity id)" value="00000001" /> </div> </div> </div> """%field_vals(width=6) formrow1b = """ <div class="small-12 medium-6 columns" title="%(tooltip1b)s"> <div class="row view-value-row"> <div class="%(label_classes)s"> <span>S/W version</span> </div> <div class="%(input_classes)s"> <span> </span> </div> </div> </div> """%field_vals(width=6) formrow2 = """ <div class="small-12 columns" title="%(tooltip2)s"> <div class="row view-value-row"> <div class="%(label_classes)s"> <span>Label</span> </div> <div class="%(input_classes)s"> <input type="text" size="64" name="Entity_label" placeholder="(label)" value="" /> </div> </div> </div> """%field_vals(width=12) formrow3 = """ <div class="small-12 columns" title="%(tooltip3)s"> <div class="row view-value-row"> <div class="%(label_classes)s"> <span>Comment</span> </div> <div class="%(input_classes)s"> <textarea cols="64" rows="6" name="Entity_comment" class="small-rows-4 medium-rows-8" placeholder="(description)" > </textarea> </div> </div> </div> """%field_vals(width=12) formrow4 = """ <div class="small-12 columns" title="%(tooltip4)s"> <div class="row view-value-row"> <div class="%(label_classes)s"> <span>Parent</span> </div> <div class="%(input_classes)s"> <select name="Coll_parent"> <option value="" selected="selected">(site)</option> <option value="_coll/_annalist_site">Annalist data notebook test site</option> <option value="_coll/coll1">Collection coll1</option> <option value="_coll/coll2">Collection coll2</option> <option value="_coll/coll3">Collection coll3</option> <option value="_coll/testcoll">Collection testcoll</option> </select> </div> </div> </div> """%field_vals(width=12) formrow5a = """ <div class="small-12 medium-6 columns" title="%(tooltip5a)s"> <div class="row view-value-row"> <div class="%(label_classes)s"> <span>Default list</span> </div> <div class="%(input_classes)s"> <span> </span> </div> </div> </div> """%field_vals(width=6) formrow5b = """ <div class="small-12 medium-6 columns" title="%(tooltip5b)s"> <div class="row view-value-row"> <div class="%(label_classes)s"> <span>Default view</span> </div> <div class="%(input_classes)s"> <span> </span> </div> </div> </div> """%field_vals(width=6) formrow6a = """ <div class="small-12 medium-6 columns" title="%(tooltip6a)s"> <div class="row view-value-row"> <div class="%(label_classes)s"> <span>Default view type</span> </div> <div class="%(input_classes)s"> <span> </span> </div> </div> </div> """%field_vals(width=6) formrow6b = """ <div class="small-12 medium-6 columns" title="%(tooltip6b)s"> <div class="row view-value-row"> <div class="%(label_classes)s"> <span>Default view entity</span> </div> <div class="%(input_classes)s"> <span> </span> </div> </div> </div> """%field_vals(width=6) formrow7 = """ <div class="small-12 columns" title="%(tooltip7)s"> <div class="row view-value-row"> <div class="%(label_classes)s"> <span>Collection metadata</span> </div> <div class="%(input_classes)s"> <textarea cols="64" rows="6" name="Coll_comment" class="small-rows-4 medium-rows-8" placeholder="(annal:meta_comment)" > </textarea> </div> </div> </div> """%field_vals(width=12) # log.info(r.content) self.assertContains(r, formrow1a, html=True) self.assertContains(r, formrow1b, html=True) self.assertContains(r, formrow2, html=True) self.assertContains(r, formrow3, html=True) self.assertContains(r, formrow4, html=True) self.assertContains(r, formrow5a, html=True) self.assertContains(r, formrow5b, html=True) self.assertContains(r, formrow6a, html=True) self.assertContains(r, formrow6b, html=True) # self.assertContains(r, formrow_viewdata, html=True) return # Collection data view def test_get_collection_data_view(self): collection_url = collection_view_url(coll_id="testcoll") u = collectiondata_url(coll_id="testcoll") r = self.client.get(u) self.assertEqual(r.status_code, 200) self.assertEqual(r.reason_phrase, "OK") self.assertEqual(r.context['coll_id'], layout.SITEDATA_ID) self.assertEqual(r.context['type_id'], layout.COLL_TYPEID) self.assertEqual(r.context['entity_id'], "testcoll") self.assertEqual(r.context['orig_id'], "testcoll") self.assertEqual(r.context['action'], "view") self.assertEqual(r.context['continuation_url'], "") self.assertEqual( r.context['entity_data_ref'], collection_url+layout.COLL_META_REF ) self.assertEqual( r.context['entity_data_ref_json'], collection_url+layout.COLL_META_REF+"?type=application/json" ) return # Collection data content negotiation def test_get_collection_data_json(self): """ Request collection data as JSON-LD """ collection_url = collection_view_url(coll_id="testcoll") u = collectiondata_url(coll_id="testcoll") r = self.client.get(u, HTTP_ACCEPT="application/ld+json") self.assertEqual(r.status_code, 302) self.assertEqual(r.reason_phrase, "FOUND") v = r['Location'] self.assertEqual(v, TestHostUri+collection_url+layout.COLL_META_REF) r = self.client.get(v) self.assertEqual(r.status_code, 200) self.assertEqual(r.reason_phrase, "OK") return # Collection data view metadata access def test_get_collection_data_view_metadata(self): u = collectiondata_resource_url(coll_id="testcoll") r = self.client.get(u) self.assertEqual(r.status_code, 200) self.assertEqual(r.reason_phrase, "OK") colldata = json.loads(r.content) expected = ( { "@id": "../" , "@type": [ "annal:Collection" ] , "@context": [ {"@base": layout.META_COLL_BASE_REF}, "coll_context.jsonld" ] , "annal:id": "testcoll" , "annal:type_id": layout.COLL_TYPEID , "annal:type": "annal:Collection" , "rdfs:label": "Collection testcoll" , "rdfs:comment": "Description of Collection testcoll" , "annal:software_version": annalist.__version_data__ }) self.assertEqual(colldata, expected) return # collection named view context def test_get_named_view(self): u = collectiondata_view_url(coll_id="testcoll", action="view") r = self.client.get(u) self.assertEqual(r.status_code, 200) self.assertEqual(r.reason_phrase, "OK") self.assertEqual(r.context['coll_id'], layout.SITEDATA_ID) self.assertEqual(r.context['type_id'], layout.COLL_TYPEID) self.assertEqual(r.context['entity_id'], "testcoll") self.assertEqual(r.context['orig_id'], "testcoll") self.assertEqual(r.context['action'], "view") self.assertEqual(r.context['continuation_url'], "") return # collection named view edit def test_get_named_edit(self): u = collectiondata_view_url(coll_id="testcoll", action="edit") r = self.client.get(u) self.assertEqual(r.status_code, 200) self.assertEqual(r.reason_phrase, "OK") self.assertEqual(r.context['coll_id'], layout.SITEDATA_ID) self.assertEqual(r.context['type_id'], layout.COLL_TYPEID) self.assertEqual(r.context['entity_id'], "testcoll") self.assertEqual(r.context['orig_id'], "testcoll") self.assertEqual(r.context['action'], "edit") self.assertEqual(r.context['continuation_url'], "") return # collection named view edit post update def test_post_named_edit(self): u = collectiondata_view_url(coll_id="testcoll", action="edit") f = coll_view_form_data(coll_id="testcoll", action="edit") r = self.client.post(u, f) self.assertEqual(r.status_code, 302) self.assertEqual(r.reason_phrase, "FOUND") self.assertEqual(r.content, "") self.assertEqual(r['location'], TestBaseUri+"/c/_annalist_site/d/_coll/") # Check updated collection data self._check_collection_data_values(coll_id="testcoll") return # collection named view metadata access def test_get_named_view_metadata(self): u = collectiondata_view_resource_url(coll_id="testcoll") log.debug("test_get_named_view_metadata: collectiondata_view_resource_url: %s"%(u,)) r = self.client.get(u) self.assertEqual(r.status_code, 200) self.assertEqual(r.reason_phrase, "OK") colldata = json.loads(r.content) expected = ( { "@id": "../" , "@type": [ "annal:Collection" ] , "@context": [ {"@base": layout.META_COLL_BASE_REF}, "coll_context.jsonld" ] , "annal:id": "testcoll" , "annal:type_id": layout.COLL_TYPEID , "annal:type": "annal:Collection" , "rdfs:label": "Collection testcoll" , "rdfs:comment": "Description of Collection testcoll" , "annal:software_version": annalist.__version_data__ }) self.assertEqual(colldata, expected) return # ----------------------------------------------------------------------------- # Form response tests # ----------------------------------------------------------------------------- def test_edit_collection_metadata(self): # This test performs a GET to retrieve values used in a form, # then a POST to save updated collection metadata. # This test is intended to test a problem encountered with updated # entity copying logic that needs to take special account of collection # entities being presented as offspring of the site while being stored # as part of a collection. # coll_id = "testcoll" self.assertTrue(Collection.exists(self.testsite, coll_id)) c = Collection.load(self.testsite, coll_id) self.assertEqual(c.get_id(), coll_id) self.assertEqual(c.get_view_url_path(), collection_view_url(coll_id="testcoll")) # GET collection metadata form data, and test values u = collectiondata_url(coll_id="testcoll") r = self.client.get(u) self.assertEqual(r.status_code, 200) self.assertEqual(r.reason_phrase, "OK") self.assertEqual(r.context['coll_id'], layout.SITEDATA_ID) self.assertEqual(r.context['type_id'], layout.COLL_TYPEID) self.assertEqual(r.context['entity_id'], "testcoll") self.assertEqual(r.context['orig_id'], "testcoll") self.assertEqual(r.context['orig_coll'], layout.SITEDATA_ID) self.assertEqual(r.context['action'], "view") self.assertEqual(r.context['continuation_url'], "") orig_coll = r.context['orig_coll'] # Assemble and POST form data to =updated collection metadata new_label = "Updated collection metadata" f = coll_view_form_data( coll_id="testcoll", action="edit", coll_label=new_label, # orig_coll="None" orig_coll=layout.SITEDATA_ID ) u = collectiondata_view_url(coll_id="testcoll", action="edit") r = self.client.post(u, f) self.assertEqual(r.status_code, 302) self.assertEqual(r.reason_phrase, "FOUND") self.assertEqual(r.content, "") self.assertEqual(r['location'], TestBaseUri+"/c/_annalist_site/d/_coll/") # Check updated collection data self._check_collection_data_values(coll_id="testcoll", coll_label=new_label) return def test_post_copy_user(self): # The main purpose of this test is to check that user permissions are # saved properly self.assertFalse(AnnalistUser.exists(self.testcoll, "copyuser")) f = user_view_form_data( action="copy", orig_id="_default_user_perms", user_id="copyuser", user_name="User copyuser", user_uri="mailto:[email protected]", user_permissions="VIEW CREATE UPDATE DELETE", orig_coll=layout.SITEDATA_ID ) u = entitydata_edit_url( "copy", "testcoll", "_user", entity_id="_default_user_perms", view_id="User_view" ) r = self.client.post(u, f) self.assertEqual(r.status_code, 302) self.assertEqual(r.reason_phrase, "FOUND") self.assertEqual(r.content, "") self.assertEqual(r['location'], TestBaseUri+"/c/testcoll/d/_user/") # Check that new record type exists self.assertTrue(AnnalistUser.exists(self.testcoll, "copyuser")) self._check_annalist_user_perms("copyuser", ["VIEW", "CREATE", "UPDATE", "DELETE"]) return
def am_updatesite(annroot, userhome, options): """ Update site data, leaving user data alone annroot is the root directory for the Annalist software installation. userhome is the home directory for the host system user issuing the command. options contains options parsed from the command line. returns 0 if all is well, or a non-zero status code. This value is intended to be used as an exit status code for the calling program. """ status = am_errors.AM_SUCCESS sitesettings = am_get_site_settings(annroot, userhome, options) if not sitesettings: print("Settings not found (%s)"%(options.configuration), file=sys.stderr) return am_errors.AM_NOSETTINGS if len(options.args) > 0: print( "Unexpected arguments for %s: (%s)"% (options.command, " ".join(options.args)), file=sys.stderr ) return am_errors.AM_UNEXPECTEDARGS site_layout = layout.Layout(sitesettings.BASE_DATA_DIR) sitebasedir = site_layout.SITE_PATH sitebaseurl = "/annalist/" # @@TODO: figure more robust way to define this site = Site(sitebaseurl, site_layout.SITE_PATH) sitedata = site.site_data_collection(test_exists=False) if sitedata is None: print("Initializing Annalist site metadata in %s (migrating to new layout)"%(sitebasedir)) site = Site.create_empty_site_data( sitebaseurl, sitebasedir, label="Annalist site (%s configuration)"%options.configuration, description="Annalist %s site metadata and site-wide values."%options.configuration ) sitedata = site.site_data_collection() site_data_src = os.path.join(annroot, "annalist/data/sitedata") # @@TODO: more robust definition site_data_tgt, site_data_file = sitedata._dir_path() # --- Migrate old site data to new site directory site_data_old = os.path.join(sitebasedir, site_layout.SITEDATA_OLD_DIR) old_users = os.path.join(site_data_old, layout.USER_DIR_PREV) old_vocabs = os.path.join(site_data_old, layout.VOCAB_DIR_PREV) if os.path.isdir(old_users) or os.path.isdir(old_vocabs): print("Copy Annalist old user and/or vocab data from %s"%site_data_old) migrate_old_data(site_data_old, layout.USER_DIR_PREV, site_data_tgt, layout.USER_DIR ) migrate_old_data(site_data_old, layout.VOCAB_DIR_PREV, site_data_tgt, layout.VOCAB_DIR) #@@ # if os.path.isdir(old_users) or os.path.isdir(old_vocabs): # print("Copy Annalist old user and/or vocab data from %s"%site_data_old) # for sdir in ("users", "vocabs"): # s = os.path.join(site_data_old, sdir) # old_s = os.path.join(site_data_old, "old_"+sdir) # d = os.path.join(site_data_tgt, sdir) # if os.path.isdir(s): # print("- %s +> %s (migrating)"%(sdir, d)) # updatetree(s, d) # print("- %s >> %s (rename)"%(sdir, old_s)) # os.rename(s, old_s) #@@ # --- Copy latest site data to target directory print("Copy Annalist site data") print("from %s"%site_data_src) for sdir in layout.DATA_DIRS: print("- %s -> %s"%(sdir, site_data_tgt)) Site.replace_site_data_dir(sitedata, sdir, site_data_src) for sdir in (layout.USER_DIR, layout.VOCAB_DIR): print("- %s +> %s"%(sdir, site_data_tgt)) Site.update_site_data_dir(sitedata, sdir, site_data_src) for sdir in layout.COLL_DIRS_PREV: remove_old_data(site_data_tgt, sdir) print("Generating %s"%(site_layout.SITEDATA_CONTEXT_DIR)) sitedata.generate_coll_jsonld_context() # --- Copy provider data to site config provider directory provider_dir_tgt = os.path.join(sitesettings.CONFIG_BASE, "providers") provider_dir_src = os.path.join(annroot, "annalist/data/identity_providers") print("Copy identity provider data:") print("- from: %s"%(provider_dir_src,)) print("- to: %s"%(provider_dir_tgt,)) updatetree(provider_dir_src, provider_dir_tgt) return status
class SiteActionViewTests(AnnalistTestCase): """ Tests for Site action views (completion of confirmed actions requested from the site view) """ def setUp(self): init_annalist_test_site() self.testsite = Site(TestBaseUri, TestBaseDir) # self.user = User.objects.create_user('testuser', '*****@*****.**', 'testpassword') # self.user.save() # self.client = Client(HTTP_HOST=TestHost) # Login and permissions create_test_user(None, "testuser", "testpassword") self.client = Client(HTTP_HOST=TestHost) loggedin = self.client.login(username="******", password="******") self.assertTrue(loggedin) create_user_permissions( self.testsite.site_data_collection(), "testuser", user_permissions= [ "VIEW", "CREATE", "UPDATE", "DELETE", "CONFIG" , "CREATE_COLLECTION", "DELETE_COLLECTION" ] ) return def tearDown(self): return @classmethod def setUpClass(cls): super(SiteActionViewTests, cls).setUpClass() # Remove any collections left behind from previous tests resetSitedata(scope="collections") return def _conf_data(self, action="confirm"): action_values = ( { 'confirm': "Confirm" , 'cancel': "Cancel" }) return ( { action: action_values[action] , "confirmed_action": reverse("AnnalistSiteActionView") , "action_params": """{"new_label": [""], "new_id": [""], "select": ["coll1", "coll3"], "remove": ["Remove selected"]}""" , "cancel_action": reverse("AnnalistSiteView") }) def test_SiteActionViewTest(self): self.assertEqual(SiteActionView.__name__, "SiteActionView", "Check SiteActionView class name") return def test_post_confirmed_remove(self): # Submit positive confirmation u = reverse("AnnalistConfirmView") r = self.client.post(u, self._conf_data(action="confirm")) self.assertEqual(r.status_code, 302) self.assertEqual(r.reason_phrase, "Found") self.assertEqual(r.content, b"") v = reverse("AnnalistSiteView") e1 = "info_head=" e2 = "info_message=" e3 = "coll1" e4 = "coll3" self.assertIn(v, r['location']) self.assertIn(e1, r['location']) self.assertIn(e2, r['location']) self.assertIn(e3, r['location']) self.assertIn(e4, r['location']) # Confirm collections deleted r = self.client.get(TestBasePath+"/site/") colls = r.context['collections'] #@@ (diagnostic only) if len(colls) != len(init_collection_keys)-2: log.warning("@@ Collection count mismatch: %s != %d"%(len(colls), len(init_collection_keys)-2)) log.warning("@@ Collections seen %r"%(list(colls),)) #@@ self.assertEqual(len(colls), len(init_collection_keys)-2) id = "coll2" self.assertEqual(colls[id]["annal:id"], id) self.assertEqual(colls[id]["annal:url"], init_collections[id]["annal:url"]) self.assertEqual(colls[id]["rdfs:label"], init_collections[id]["rdfs:label"]) return def test_post_cancelled_remove(self): u = reverse("AnnalistConfirmView") r = self.client.post(u, self._conf_data(action="cancel")) self.assertEqual(r.status_code, 302) self.assertEqual(r.reason_phrase, "Found") self.assertEqual(r.content, b"") self.assertEqual(r['location'], TestBasePath+"/site/") # Confirm no collections deleted r = self.client.get(TestBasePath+"/site/") colls = r.context['collections'] self.assertEqual(len(colls), len(init_collection_keys)) for id in init_collections: self.assertEqual(colls[id]["annal:id"], id) self.assertEqual(colls[id]["annal:url"], init_collections[id]["annal:url"]) self.assertEqual(colls[id]["rdfs:label"], init_collections[id]["rdfs:label"]) return
class SiteViewTest(AnnalistTestCase): """ Tests for Site views """ def setUp(self): init_annalist_test_site() self.testsite = Site(TestBaseUri, TestBaseDir) self.uri = reverse("AnnalistSiteView") self.homeuri = reverse("AnnalistHomeView") self.profileuri = reverse("AnnalistProfileView") # Login and permissions create_test_user(None, "testuser", "testpassword") self.client = Client(HTTP_HOST=TestHost) loggedin = self.client.login(username="******", password="******") self.assertTrue(loggedin) create_user_permissions( self.testsite.site_data_collection(), "testuser", user_permissions= [ "VIEW", "CREATE", "UPDATE", "DELETE", "CONFIG" , "CREATE_COLLECTION", "DELETE_COLLECTION" ] ) return def tearDown(self): return @classmethod def setUpClass(cls): super(SiteViewTest, cls).setUpClass() return @classmethod def tearDownClass(cls): super(SiteViewTest, cls).tearDownClass() resetSitedata(scope="all") return def test_SiteViewTest(self): self.assertEqual(SiteView.__name__, "SiteView", "Check SiteView class name") return def test_get(self): # @@TODO: use reference to self.client, per # https://docs.djangoproject.com/en/dev/topics/testing/tools/#default-test-client r = self.client.get(self.uri) self.assertEqual(r.status_code, 200) self.assertEqual(r.reason_phrase, "OK") self.assertContains(r, site_title("<title>%s</title>")) return def test_get_error(self): r = self.client.get(self.uri+"?error_head=Error&error_message=Error%20presented") self.assertEqual(r.status_code, 200) self.assertEqual(r.reason_phrase, "OK") self.assertContains(r, """<h3>Error</h3>""", html=True) self.assertContains(r, """<p class="messages">Error presented</p>""", html=True) return def test_get_info(self): r = self.client.get(self.uri+"?info_head=Information&info_message=Information%20presented") self.assertEqual(r.status_code, 200) self.assertEqual(r.reason_phrase, "OK") self.assertContains(r, """<h3>Information</h3>""", html=True) self.assertContains(r, """<p class="messages">Information presented</p>""", html=True) return def test_get_home(self): r = self.client.get(self.homeuri) self.assertEqual(r.status_code, 302) self.assertEqual(r.reason_phrase, "Found") self.assertEqual(r["location"], self.uri) return def test_get_no_login(self): self.client.logout() r = self.client.get(self.uri) self.assertFalse(r.context["auth_create"]) self.assertFalse(r.context["auth_update"]) self.assertFalse(r.context["auth_delete"]) colls = r.context['collections'] self.assertEqual(len(colls), len(init_collection_keys)) for id in init_collections: self.assertEqual(colls[id]["annal:id"], id) self.assertEqual(colls[id]["annal:url"], init_collections[id]["annal:url"]) self.assertEqual(colls[id]["rdfs:label"], init_collections[id]["rdfs:label"]) # Check returned HTML (checks template logic) # (Don't need to keep doing this as logic can be tested through context as above) # (See: http://stackoverflow.com/questions/2257958/) s = BeautifulSoup(r.content, "html.parser") self.assertEqual(s.html.title.string, site_title()) homelink = s.find(class_="title-area").find(class_="name").h1.a self.assertEqual(homelink.string, "Home") self.assertEqual(homelink['href'], self.uri) menuitems = s.find(class_="top-bar-section").find(class_="right").find_all("li") self.assertEqualIgnoreWS(menuitems[0].a.string, "Login") self.assertEqual(menuitems[0].a['href'], self.profileuri) # Check displayed collections trows = s.form.find_all("div", class_="tbody") self.assertEqual(len(trows), len(init_collection_keys)) self.assertEqual(trows[0].div.div('div')[1].a.string, "_annalist_site") self.assertEqual(trows[0].div.div('div')[1].a['href'], collection_view_url("_annalist_site")) self.assertEqual(trows[1].div.div('div')[1].a.string, "coll1") self.assertEqual(trows[1].div.div('div')[1].a['href'], collection_view_url("coll1")) self.assertEqual(trows[2].div.div('div')[1].a.string, "coll2") self.assertEqual(trows[2].div.div('div')[1].a['href'], collection_view_url("coll2")) self.assertEqual(trows[3].div.div('div')[1].a.string, "coll3") self.assertEqual(trows[3].div.div('div')[1].a['href'], collection_view_url("coll3")) return def test_get_with_login(self): r = self.client.get(self.uri) # Preferred way to test main view logic self.assertTrue(r.context["auth_create"]) self.assertTrue(r.context["auth_update"]) self.assertTrue(r.context["auth_delete"]) self.assertTrue(r.context["auth_create_coll"]) self.assertTrue(r.context["auth_delete_coll"]) colls = r.context['collections'] self.assertEqual(len(colls), len(init_collection_keys)) for id in init_collections: # First two here added in models.site.site_data() self.assertEqual(colls[id]["id"], id) self.assertEqual(colls[id]["url"], init_collections[id]["annal:url"]) self.assertEqual(colls[id]["annal:id"], id) self.assertEqual(colls[id]["annal:url"], init_collections[id]["annal:url"]) self.assertEqual(colls[id]["rdfs:label"], init_collections[id]["rdfs:label"]) # Check returned HTML (checks template logic) # (Don't need to keep doing this as logic can be tested through context as above) # (See: http://stackoverflow.com/questions/2257958/) s = BeautifulSoup(r.content, "html.parser") # title and top menu self.assertEqual(s.html.title.string, site_title()) homelink = s.find(class_="title-area").find(class_="name").h1.a self.assertEqual(homelink.string, "Home") self.assertEqual(homelink['href'], self.uri) menuitems = s.find(class_="top-bar-section").find(class_="right").find_all("li") self.assertEqualIgnoreWS(menuitems[0].a.string, "User testuser") self.assertEqual(menuitems[0].a['href'], TestBasePath+"/profile/") self.assertEqualIgnoreWS(menuitems[1].a.string, "Logout") self.assertEqual(menuitems[1].a['href'], TestBasePath+"/logout/") # Displayed colllections and check-buttons # trows = s.form.find_all("div", class_="tbody") trows = s.select("form > div > div > div") self.assertEqual(len(trows), len(init_collection_keys)+4) site_data = ( [ (1, "checkbox", "select", "_annalist_site") , (2, "checkbox", "select", "coll1") , (3, "checkbox", "select", "coll2") , (4, "checkbox", "select", "coll3") ]) for i, itype, iname, ivalue in site_data: # tcols = trows[i].find_all("div", class_="view-value") tcols = trows[i].select("div > div > div") self.assertEqual(tcols[0].input['type'], itype) self.assertEqual(tcols[0].input['name'], iname) self.assertEqual(tcols[0].input['value'], ivalue) self.assertEqual(tcols[1].a.string, ivalue) self.assertEqual(tcols[1].a['href'], collection_view_url(ivalue)) # buttons to view/edit/remove selected btn_view = trows[5].select("div > input")[0] self.assertEqual(btn_view["type"], "submit") self.assertEqual(btn_view["name"], "view") btn_edit = trows[5].select("div > input")[1] self.assertEqual(btn_edit["type"], "submit") self.assertEqual(btn_edit["name"], "edit") btn_remove = trows[5].select("div > input")[2] self.assertEqual(btn_remove["type"], "submit") self.assertEqual(btn_remove["name"], "remove") # Input fields for new collection add_fields = trows[6].select("div > div > div") field_id = add_fields[1].input field_label = add_fields[2].input self.assertEqual(field_id["type"], "text") self.assertEqual(field_id["name"], "new_id") self.assertEqual(field_label["type"], "text") self.assertEqual(field_label["name"], "new_label") # Button for new collection btn_new = trows[7].select("div > input")[0] self.assertEqual(btn_new["type"], "submit") self.assertEqual(btn_new["name"], "new") return def test_get_site_context_resource(self): u = reverse("AnnalistSiteResourceAccess", kwargs={"resource_ref": layout.SITE_CONTEXT_FILE}) r = self.client.get(u) self.assertEqual(r.status_code, 200) self.assertEqual(r.reason_phrase, "OK") self.assertEqual(r["content-type"], "application/ld+json") return def test_get_site_image_resource(self): self.testsite._ensure_values_loaded() self.testsite["testimage"] = ( { "resource_name": "test-image.jpg" , "resource_type": "image/jpeg" }) self.testsite._save() u = reverse("AnnalistSiteResourceAccess", kwargs={"resource_ref": "test-image.jpg"}) r = self.client.get(u) self.assertEqual(r.status_code, 200) self.assertEqual(r.reason_phrase, "OK") self.assertEqual(r["content-type"], "image/jpeg") return def test_get_site_markdown_resource(self): self.testsite._ensure_values_loaded() self.testsite["testdatafile"] = ( { "resource_name": "testdatafile.md" , "resource_type": "text/markdown" }) self.testsite._save() u = reverse("AnnalistSiteResourceAccess", kwargs={"resource_ref": "testdatafile.md"}) r = self.client.get(u) self.assertEqual(r.status_code, 200) self.assertEqual(r.reason_phrase, "OK") self.assertEqual(r["content-type"], "text/markdown") return def test_get_site_nonexistent_resource(self): self.testsite._ensure_values_loaded() self.testsite["nosuchfile"] = ( { "resource_name": "nosuch.file" , "resource_type": "text/plain" }) self.testsite._save() u = reverse("AnnalistSiteResourceAccess", kwargs={"resource_ref": "nosuch.file"}) r = self.client.get(u) self.assertEqual(r.status_code, 404) self.assertEqual(r.reason_phrase, "Not found") return def test_post_add(self): form_data = collection_new_form_data("testnew") r = self.client.post(self.uri, form_data) self.assertEqual(r.status_code, 302) self.assertEqual(r.reason_phrase, "Found") self.assertEqual(r.content, b"") self.assertEqual(r['location'], TestBasePath+"/site/" "?info_head=Action%20completed"+ "&info_message=Created%20new%20collection:%20'testnew'") # Check site now has new colllection r = self.client.get(self.uri) new_collections = init_collections.copy() new_collections["testnew"] = collection_values("testnew", hosturi=TestHostUri) colls = r.context['collections'] for id in new_collections: p = "[%s]"%id # First two here added in model.site.site_data for view template self.assertEqualPrefix(colls[id]["id"], id, p) self.assertEqualPrefix(colls[id]["url"], new_collections[id]["annal:url"], p) self.assertEqualPrefix(colls[id]["annal:id"], id, p) self.assertEqualPrefix(colls[id]["annal:url"], new_collections[id]["annal:url"], p) self.assertEqualPrefix(colls[id]["rdfs:label"], new_collections[id]["rdfs:label"], p) # Check new collection has admin permissions for creator new_coll = Collection(self.testsite, "testnew") testuser_perms = new_coll.get_user_permissions("testuser", "mailto:testuser@%s"%TestHost) expect_perms = ["VIEW", "CREATE", "UPDATE", "DELETE", "CONFIG", "ADMIN"] expect_descr = "User testuser: permissions for Test User in collection testnew" self.assertEqual(testuser_perms[ANNAL.CURIE.id], "testuser") self.assertEqual(testuser_perms[RDFS.CURIE.label], "Test User") self.assertEqual(testuser_perms[RDFS.CURIE.comment], expect_descr) self.assertEqual(testuser_perms[ANNAL.CURIE.user_uri], "mailto:testuser@%s"%TestHost) self.assertEqual(testuser_perms[ANNAL.CURIE.user_permission], expect_perms) return def test_post_remove(self): form_data = collection_remove_form_data(["coll1", "coll3"]) r = self.client.post(self.uri, form_data) self.assertEqual(r.status_code, 200) self.assertEqual(r.reason_phrase, "OK") self.assertTemplateUsed(r, "annalist_confirm.html") # Returns confirmation form: check self.assertContains(r, '''<form method="POST" action="'''+TestBasePath+'''/confirm/">''', status_code=200) self.assertContains(r, '''<input type="submit" name="confirm" value="Confirm"/>''', html=True) self.assertContains(r, '''<input type="submit" name="cancel" value="Cancel"/>''', html=True) self.assertContains(r, '''<input type="hidden" name="confirmed_action" value="'''+reverse("AnnalistSiteActionView")+'''"/>''', html=True) self.assertContains(r, '''<input type="hidden" name="cancel_action" value="'''+reverse("AnnalistSiteView")+'''"/>''', html=True) self.assertHtmlContentElement(r.content, tagname="input", tagattrs={"name": "action_params"}, expect_attrs= { "type": "hidden" , "value": { "remove": ["Remove selected"] , "new_id": [""] , "new_label": [""] , "select": ["coll1", "coll3"] } } ) return