Browse Source

MySQL deadlock fix, more cypress tests, optimization

Vova Tkach 6 years ago
parent
commit
e6d5e63462

+ 9 - 2
cypress/integration/control-panel/001_module_index/001_install_mysql.spec.js

@@ -3,8 +3,15 @@
 context('Install MySQL, create first user and login', () => {
   it('should do redirect to cp panel', () => {
     cy.resetCMS();
-    cy.visitCMS('/');
-    cy.url().should('eq', 'http://localhost:8080/cp/');
+    cy.request({
+      url: cy.getBaseUrl() + '/',
+      followRedirect: false
+    }).then((response) => {
+      expect(response.status).to.eq(302);
+      expect(response.redirectedToUrl).to.eq(cy.getBaseUrl() + '/cp/');
+    });
+    cy.visitCMS('/cp/');
+    cy.url().should('eq', cy.getBaseUrl() + '/cp/');
   });
 
   it('should configure mysql config', () => {

+ 0 - 3
cypress/integration/control-panel/001_module_index/002_top_nav_bar.js

@@ -14,15 +14,12 @@ context('Top navigation bar', () => {
   it('should render modules menu', () => {
     cy.loginCMS();
     cy.get('#navbarCollapse ul.navbar-nav:nth-child(1) li.nav-item').should('have.length', 2);
-
     cy.get('#navbarCollapse ul.navbar-nav li.nav-item a.nav-link').should('contain', 'Modules');
     cy.contains('#navbarCollapse ul.navbar-nav li.nav-item a.nav-link', 'Modules').parent().find('.dropdown-menu .dropdown-item').should('contain', 'Pages');
     cy.contains('#navbarCollapse ul.navbar-nav li.nav-item a.nav-link', 'Modules').parent().find('.dropdown-menu .dropdown-item').should('contain', 'Blog');
-
     cy.get('#navbarCollapse ul.navbar-nav li.nav-item a.nav-link').should('contain', 'System');
     cy.contains('#navbarCollapse ul.navbar-nav li.nav-item a.nav-link', 'System').parent().find('.dropdown-menu .dropdown-item').should('contain', 'Users');
     cy.contains('#navbarCollapse ul.navbar-nav li.nav-item a.nav-link', 'System').parent().find('.dropdown-menu .dropdown-item').should('contain', 'Settings');
-
     cy.logoutCMS();
   });
 

+ 83 - 0
cypress/integration/control-panel/003_module_users/001_users.js

@@ -0,0 +1,83 @@
+/// <reference types="Cypress" />
+
+context('Module users', () => {
+  it('should reset', () => {
+    cy.installCMS();
+  });
+
+  it('should render data table', () => {
+    cy.loginCMS();
+    cy.visitCMS('/cp/users/');
+    cy.get('table.data-table thead tr').should('have.length', 1);
+    cy.get('table.data-table thead tr th').should('have.length', 4);
+    cy.get('table.data-table tbody tr').should('have.length', 1);
+    cy.get('table.data-table tbody tr:nth-child(1) td').should('have.length', 4);
+    cy.logoutCMS();
+  });
+
+  it('should render data form', () => {
+    cy.loginCMS();
+    cy.visitCMS('/cp/users/add/');
+    cy.get('.data-form.users-add input[type=text]').should('have.length', 2);
+    cy.get('.data-form.users-add input[type=email]').should('have.length', 1);
+    cy.get('.data-form.users-add input[type=password]').should('have.length', 1);
+    cy.get('.data-form.users-add input[type=checkbox]').should('have.length', 2);
+    cy.logoutCMS();
+  });
+
+  it('should not add new user', () => {
+    cy.loginCMS();
+    cy.visitCMS('/cp/users/add/');
+    cy.get('.data-form.users-add input[name=email]').clear().type('some@text');
+    cy.get('.data-form.users-add input[name=password]').clear().type('some@text');
+    cy.get('#add-edit-button').click();
+    cy.actionWait();
+    cy.get('.data-form.users-add div.sys-messages').should('exist');
+    cy.logoutCMS();
+  });
+
+  it('should add new user', () => {
+    cy.loginCMS();
+    cy.visitCMS('/cp/users/add/');
+    cy.get('.data-form.users-add input[name=first_name]').clear().type('Some user first name');
+    cy.get('.data-form.users-add input[name=last_name]').clear().type('Some user last name');
+    cy.get('.data-form.users-add input[name=email]').clear().type('some@user.com');
+    cy.get('.data-form.users-add input[name=password]').clear().type('some@text');
+    cy.get('.data-form.users-add label[for=lbl_active]').click();
+    cy.get('.data-form.users-add label[for=lbl_admin]').click();
+    cy.get('#add-edit-button').click();
+    cy.actionWait();
+    cy.logoutCMS();
+  });
+
+  it('should render added user in list', () => {
+    cy.loginCMS();
+    cy.visitCMS('/cp/users/');
+    cy.get('table.data-table tbody tr').should('have.length', 2);
+    cy.get('table.data-table tbody tr td').should('contain', 'some@user.com');
+    cy.contains('table.data-table tbody tr td a', 'some@user.com').parentsUntil('tr').parent().find('.svg-green').should('exist');
+    cy.logoutCMS();
+  });
+
+  it('should render added user in edit form', () => {
+    cy.loginCMS();
+    cy.visitCMS('/cp/users/');
+    cy.contains('table.data-table tbody tr td a', 'some@user.com').click();
+    cy.get('.data-form.users-modify input[name=first_name]').should('have.value', 'Some user first name');
+    cy.get('.data-form.users-modify input[name=last_name]').should('have.value', 'Some user last name');
+    cy.get('.data-form.users-modify input[name=email]').should('have.value', 'some@user.com');
+    cy.get('.data-form.users-modify input[name=password]').should('have.value', '');
+    cy.get('.data-form.users-modify input[name=active]').should('be.checked');
+    cy.get('.data-form.users-modify input[name=admin]').should('be.checked');
+    cy.logoutCMS();
+  });
+
+  it('should delete added user', () => {
+    cy.loginCMS();
+    cy.visitCMS('/cp/users/');
+    cy.contains('table.data-table tbody tr td a', 'some@user.com').parentsUntil('tr').parent().find('td a.ico.delete').click();
+    cy.actionWait();
+    cy.get('table.data-table tbody tr').should('have.length', 1);
+    cy.logoutCMS();
+  });
+});

+ 63 - 0
cypress/integration/control-panel/004_module_settings/001_robots_txt.js

@@ -0,0 +1,63 @@
+/// <reference types="Cypress" />
+
+context('Module robots.txt', () => {
+  it('should reset', () => {
+    cy.installCMS();
+  });
+
+  it('should render edit form', () => {
+    cy.loginCMS();
+    cy.visitCMS('/cp/settings/');
+    cy.get('.data-form.settings- textarea[name=content]').should('exist');
+    cy.get('.data-form.settings- textarea[name=content]').should('have.value', 'User-agent: *\nDisallow: /\n\n');
+    cy.logoutCMS();
+  });
+
+  it('should render result file', () => {
+    cy.request({
+      url: cy.getBaseUrl() + '/robots.txt',
+      followRedirect: false
+    }).then((response) => {
+      expect(response.status).to.eq(200);
+      expect(response.body).to.eq('User-agent: *\nDisallow: /\n\n');
+    });
+  });
+
+  it('should change file content', () => {
+    cy.loginCMS();
+
+    cy.visitCMS('/cp/settings/');
+    cy.get('.data-form.settings- textarea[name=content]').clear().type('Some file content');
+    cy.get('#add-edit-button').click();
+    cy.actionWait();
+
+    cy.visitCMS('/cp/settings/');
+    cy.get('.data-form.settings- textarea[name=content]').should('have.value', 'Some file content');
+
+    cy.request({
+      url: cy.getBaseUrl() + '/robots.txt',
+      followRedirect: false
+    }).then((response) => {
+      expect(response.status).to.eq(200);
+      expect(response.body).to.eq('Some file content');
+    });
+
+    cy.visitCMS('/cp/settings/');
+    cy.get('.data-form.settings- textarea[name=content]').clear().type('User-agent: *\nDisallow: /\n\n');
+    cy.get('#add-edit-button').click();
+    cy.actionWait();
+
+    cy.visitCMS('/cp/settings/');
+    cy.get('.data-form.settings- textarea[name=content]').should('have.value', 'User-agent: *\nDisallow: /\n\n');
+
+    cy.request({
+      url: cy.getBaseUrl() + '/robots.txt',
+      followRedirect: false
+    }).then((response) => {
+      expect(response.status).to.eq(200);
+      expect(response.body).to.eq('User-agent: *\r\nDisallow: /\r\n\r\n');
+    });
+
+    cy.logoutCMS();
+  });
+});

+ 4 - 0
cypress/support/commands.js

@@ -28,6 +28,10 @@ function getBaseUrl() {
   return 'http://localhost:8080';
 }
 
+cy.getBaseUrl = function() {
+  return getBaseUrl();
+}
+
 Cypress.Commands.add('visitCMS', (url) => {
   cy.visit(getBaseUrl() + url);
 });

+ 3 - 3
hosts/localhost/template/robots.txt

@@ -1,3 +1,3 @@
-User-agent: *
-Disallow: /
-
+User-agent: *
+Disallow: /
+

+ 2 - 12
modules/module_blog_act_delete.go

@@ -18,12 +18,7 @@ func (this *Modules) RegisterAction_BlogDelete() *Action {
 			return
 		}
 
-		// Start transaction with table lock
-		_, err := wrap.DB.Exec("LOCK TABLES blog_posts WRITE, blog_cat_post_rel WRITE;")
-		if err != nil {
-			wrap.MsgError(err.Error())
-			return
-		}
+		// Start transaction
 		tx, err := wrap.DB.Begin()
 		if err != nil {
 			wrap.MsgError(err.Error())
@@ -42,17 +37,12 @@ func (this *Modules) RegisterAction_BlogDelete() *Action {
 			return
 		}
 
-		// Commit all changes and unlock table
+		// Commit all changes
 		err = tx.Commit()
 		if err != nil {
 			wrap.MsgError(err.Error())
 			return
 		}
-		_, err = wrap.DB.Exec("UNLOCK TABLES;")
-		if err != nil {
-			wrap.MsgError(err.Error())
-			return
-		}
 
 		// Reload current page
 		wrap.Write(`window.location.reload(false);`)

+ 4 - 24
modules/module_blog_act_modify.go

@@ -43,12 +43,7 @@ func (this *Modules) RegisterAction_BlogModify() *Action {
 		}
 
 		if pf_id == "0" {
-			// Start transaction with table lock
-			_, err := wrap.DB.Exec("LOCK TABLE blog_cats WRITE, blog_cat_post_rel WRITE;")
-			if err != nil {
-				wrap.MsgError(err.Error())
-				return
-			}
+			// Start transaction
 			tx, err := wrap.DB.Begin()
 			if err != nil {
 				wrap.MsgError(err.Error())
@@ -123,26 +118,16 @@ func (this *Modules) RegisterAction_BlogModify() *Action {
 				}
 			}
 
-			// Commit all changes and unlock table
+			// Commit all changes
 			err = tx.Commit()
 			if err != nil {
 				wrap.MsgError(err.Error())
 				return
 			}
-			_, err = wrap.DB.Exec("UNLOCK TABLES;")
-			if err != nil {
-				wrap.MsgError(err.Error())
-				return
-			}
 
 			wrap.Write(`window.location='/cp/blog/';`)
 		} else {
-			// Start transaction with table lock
-			_, err := wrap.DB.Exec("LOCK TABLE blog_cats WRITE, blog_cat_post_rel WRITE;")
-			if err != nil {
-				wrap.MsgError(err.Error())
-				return
-			}
+			// Start transaction
 			tx, err := wrap.DB.Begin()
 			if err != nil {
 				wrap.MsgError(err.Error())
@@ -215,17 +200,12 @@ func (this *Modules) RegisterAction_BlogModify() *Action {
 				}
 			}
 
-			// Commit all changes and unlock table
+			// Commit all changes
 			err = tx.Commit()
 			if err != nil {
 				wrap.MsgError(err.Error())
 				return
 			}
-			_, err = wrap.DB.Exec("UNLOCK TABLES;")
-			if err != nil {
-				wrap.MsgError(err.Error())
-				return
-			}
 
 			wrap.Write(`window.location='/cp/blog/modify/` + pf_id + `/';`)
 		}

+ 13 - 10
modules/module_blog_categories_act_delete.go

@@ -18,17 +18,25 @@ func (this *Modules) RegisterAction_BlogCategoriesDelete() *Action {
 			return
 		}
 
-		// Start transaction with table lock
-		_, err := wrap.DB.Exec("LOCK TABLES blog_cats WRITE, blog_cat_post_rel WRITE;")
+		// Start transaction
+		tx, err := wrap.DB.Begin()
 		if err != nil {
 			wrap.MsgError(err.Error())
 			return
 		}
-		tx, err := wrap.DB.Begin()
-		if err != nil {
+
+		// -------------------------------------------
+		if _, err = tx.Exec("SELECT id FROM blog_cats LOCK IN SHARE MODE;"); err != nil {
+			tx.Rollback()
 			wrap.MsgError(err.Error())
 			return
 		}
+		if _, err = tx.Exec("SELECT id FROM blog_cat_post_rel WHERE category_id = ? LOCK IN SHARE MODE;", pf_id); err != nil {
+			tx.Rollback()
+			wrap.MsgError(err.Error())
+			return
+		}
+		// -------------------------------------------
 
 		// Update and delete target category
 		if _, err = tx.Exec("SELECT @ml := lft, @mr := rgt FROM blog_cats WHERE id = ?;", pf_id); err != nil {
@@ -62,17 +70,12 @@ func (this *Modules) RegisterAction_BlogCategoriesDelete() *Action {
 			return
 		}
 
-		// Commit all changes and unlock table
+		// Commit all changes
 		err = tx.Commit()
 		if err != nil {
 			wrap.MsgError(err.Error())
 			return
 		}
-		_, err = wrap.DB.Exec("UNLOCK TABLES;")
-		if err != nil {
-			wrap.MsgError(err.Error())
-			return
-		}
 
 		// Reload current page
 		wrap.Write(`window.location.reload(false);`)

+ 4 - 20
modules/module_blog_categories_act_modify.go

@@ -6,11 +6,7 @@ import (
 )
 
 func (this *Modules) blog_ActionCategoryAdd(wrap *wrapper.Wrapper, pf_id, pf_name, pf_alias, pf_parent string) error {
-	// Start transaction with table lock
-	_, err := wrap.DB.Exec("LOCK TABLE blog_cats WRITE;")
-	if err != nil {
-		return err
-	}
+	// Start transaction
 	tx, err := wrap.DB.Begin()
 	if err != nil {
 		return err
@@ -38,15 +34,11 @@ func (this *Modules) blog_ActionCategoryAdd(wrap *wrapper.Wrapper, pf_id, pf_nam
 		return err
 	}
 
-	// Commit all changes and unlock table
+	// Commit all changes
 	err = tx.Commit()
 	if err != nil {
 		return err
 	}
-	_, err = wrap.DB.Exec("UNLOCK TABLES;")
-	if err != nil {
-		return err
-	}
 
 	return nil
 }
@@ -71,11 +63,7 @@ func (this *Modules) blog_ActionCategoryUpdate(wrap *wrapper.Wrapper, pf_id, pf_
 		return err
 	} else {
 		// Parent is changed, move category to new parent
-		// Start transaction with table lock
-		_, err := wrap.DB.Exec("LOCK TABLE blog_cats WRITE;")
-		if err != nil {
-			return err
-		}
+		// Start transaction
 		tx, err := wrap.DB.Begin()
 		if err != nil {
 			return err
@@ -125,15 +113,11 @@ func (this *Modules) blog_ActionCategoryUpdate(wrap *wrapper.Wrapper, pf_id, pf_
 			return err
 		}
 
-		// Commit all changes and unlock table
+		// Commit all changes
 		err = tx.Commit()
 		if err != nil {
 			return err
 		}
-		_, err = wrap.DB.Exec("UNLOCK TABLES;")
-		if err != nil {
-			return err
-		}
 	}
 
 	return nil

+ 2 - 12
modules/module_index.go

@@ -415,12 +415,7 @@ func (this *Modules) RegisterAction_IndexDelete() *Action {
 			return
 		}
 
-		// Start transaction with table lock
-		_, err := wrap.DB.Exec("LOCK TABLES pages WRITE;")
-		if err != nil {
-			wrap.MsgError(err.Error())
-			return
-		}
+		// Start transaction
 		tx, err := wrap.DB.Begin()
 		if err != nil {
 			wrap.MsgError(err.Error())
@@ -434,17 +429,12 @@ func (this *Modules) RegisterAction_IndexDelete() *Action {
 			return
 		}
 
-		// Commit all changes and unlock table
+		// Commit all changes
 		err = tx.Commit()
 		if err != nil {
 			wrap.MsgError(err.Error())
 			return
 		}
-		_, err = wrap.DB.Exec("UNLOCK TABLES;")
-		if err != nil {
-			wrap.MsgError(err.Error())
-			return
-		}
 
 		// Reload current page
 		wrap.Write(`window.location.reload(false);`)

+ 2 - 12
modules/module_users_act_delete.go

@@ -18,12 +18,7 @@ func (this *Modules) RegisterAction_UsersDelete() *Action {
 			return
 		}
 
-		// Start transaction with table lock
-		_, err := wrap.DB.Exec("LOCK TABLES blog_cats WRITE, blog_posts WRITE, pages WRITE, users WRITE;")
-		if err != nil {
-			wrap.MsgError(err.Error())
-			return
-		}
+		// Start transaction
 		tx, err := wrap.DB.Begin()
 		if err != nil {
 			wrap.MsgError(err.Error())
@@ -52,17 +47,12 @@ func (this *Modules) RegisterAction_UsersDelete() *Action {
 			return
 		}
 
-		// Commit all changes and unlock table
+		// Commit all changes
 		err = tx.Commit()
 		if err != nil {
 			wrap.MsgError(err.Error())
 			return
 		}
-		_, err = wrap.DB.Exec("UNLOCK TABLES;")
-		if err != nil {
-			wrap.MsgError(err.Error())
-			return
-		}
 
 		// Reload current page
 		wrap.Write(`window.location.reload(false);`)