View Issue Details

IDProjectCategoryView StatusLast Update
0011873mantisbtapi soappublic2010-07-29 10:45
Reporternerville Assigned Torombert  
PrioritynormalSeverityfeatureReproducibilityalways
Status closedResolutionfixed 
Product Version1.2.1 
Target Version1.2.2Fixed in Version1.2.2 
Summary0011873: [patch] Add and delete category of a specific project using SOAP API
Description

Please find as attachment a patch to add ability to add/delete/rename categories of a specific project using SOAP API.

Currently, the SOAP API in 1.2.1 is not providing such functions.

The patch is ready to use on mantisbt 1.2.1.
I didn't try on the

Tagspatch
Attached Files
soap-categories.patch (12,453 bytes)   
From 41c28074ca8bb931560654c1bb7f0d1d998e9808 Mon Sep 17 00:00:00 2001
From: Franck Villaume <franck.villaume@capgemini.com>
Date: Mon, 3 May 2010 15:40:40 +0200
Subject: [PATCH 1/2] API SOAP features : add, delete, rename categories for a specific project

Signed-off-by: Robert Munteanu <robert.munteanu@gmail.com>
---
 api/soap/mantisconnect.php  |   52 +++++++++++++++++++++++
 api/soap/mc_project_api.php |   95 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 147 insertions(+), 0 deletions(-)

diff --git a/api/soap/mantisconnect.php b/api/soap/mantisconnect.php
index f2bae97..da61187 100644
--- a/api/soap/mantisconnect.php
+++ b/api/soap/mantisconnect.php
@@ -1074,6 +1074,58 @@ $l_oServer->register( 'mc_project_get_categories',
 	'Get the categories belonging to the specified project.'
 );
 
+### mc_project_add_category
+$l_oServer->register( 'mc_project_add_category',
+        array(
+                'username'              =>      'xsd:string',
+                'password'              =>      'xsd:string',
+                'project_id'            =>      'xsd:integer',
+                'p_category_name'       =>      'xsd:string',
+        ),
+        array(
+                'return'                =>      'xsd:integer'
+        ),
+        $t_namespace,
+        false, false, false,
+        'Add a category of specific project.'
+);
+
+
+### mc_project_delete_category
+$l_oServer->register( 'mc_project_delete_category',
+        array(
+                'username'              =>      'xsd:string',
+                'password'              =>      'xsd:string',
+                'project_id'            =>      'xsd:integer',
+                'p_category_name'       =>      'xsd:string',
+        ),
+        array(
+                'return'                =>      'xsd:integer'
+        ),
+        $t_namespace,
+        false, false, false,
+        'Delete a category of specific project.'
+);
+
+
+### mc_project_rename_category_by_name
+$l_oServer->register( 'mc_project_rename_category_by_name',
+        array(
+                'username'              =>      'xsd:string',
+                'password'              =>      'xsd:string',
+                'project_id'            =>      'xsd:integer',
+                'p_category_name'       =>      'xsd:string',
+                'p_category_name_new'   =>      'xsd:string',
+                'p_assigned_to'         =>      'xsd:integer',
+        ),
+        array(
+                'return'                =>      'xsd:integer'
+        ),
+        $t_namespace,
+        false, false, false,
+        'Rename a category of specific project.'
+);
+
 ### mc_project_get_versions
 $l_oServer->register( 'mc_project_get_versions',
 	array(
diff --git a/api/soap/mc_project_api.php b/api/soap/mc_project_api.php
index cad8336..04a3a72 100644
--- a/api/soap/mc_project_api.php
+++ b/api/soap/mc_project_api.php
@@ -105,6 +105,101 @@ function mc_project_get_categories( $p_username, $p_password, $p_project_id ) {
 }
 
 /**
+ * Add a new category to a project
+ * @param string $p_username  The name of the user trying to access the categories.
+ * @param string $p_password  The password of the user.
+ * @param integer $p_project_id  The id of the project to retrieve the categories for.
+ * @param string $p_category_name The name of the new category to add
+ * @return integer id of the new category
+ */
+
+function mc_project_add_category($p_username, $p_password, $p_project_id, $p_category_name ) {
+        $t_user_id = mci_check_login( $p_username, $p_password );
+
+        if( $t_user_id === false ) {
+                return new soap_fault( 'Client', '', 'Access Denied' );
+        }
+
+        if( !project_exists( $p_project_id ) ) {
+                return new soap_fault( 'Client', '', "Project '$p_project_id' does not exist." );
+        }
+
+        if( !mci_has_access( config_get( 'manage_project_threshold' ), $p_project_id ) ) {
+                return new soap_fault( 'Client', '', 'Access Denied' );
+        }
+
+        return category_add( $p_project_id, $p_category_name );
+}
+
+/**
+ * Delete a category of a project
+ * @param string $p_username  The name of the user trying to access the categories.
+ * @param string $p_password  The password of the user.
+ * @param integer $p_project_id  The id of the project to retrieve the categories for.
+ * @param string $p_category_name The name of the category to delete
+ * @return bool returns true or false depending on the success of the delete action
+ */
+
+function mc_project_delete_category ($p_username, $p_password, $p_project_id, $p_category_name) {
+        $t_user_id = mci_check_login( $p_username, $p_password );
+
+        if( $t_user_id === false ) {
+                return new soap_fault( 'Client', '', 'Access Denied' );
+        }
+
+        if( !project_exists( $p_project_id ) ) {
+                return new soap_fault( 'Client', '', "Project '$p_project_id' does not exist." );
+        }
+
+        if( !mci_has_access( config_get( 'manage_project_threshold' ), $p_project_id ) ) {
+                return new soap_fault( 'Client', '', 'Access Denied' );
+        }
+
+        // find the id of the category
+        $p_category_id = category_get_id_by_name( $p_category_name, $p_project_id );
+
+        // delete the category and link all the issue to the general category by default
+        return category_remove( $p_category_id, 1 );
+}
+
+/**
+ * Update a category of a project
+ * @param string $p_username  The name of the user trying to access the categories.
+ * @param string $p_password  The password of the user.
+ * @param integer $p_project_id  The id of the project to retrieve the categories for.
+ * @param string $p_category_name The name of the category to rename
+ * @param string $p_category_name_new The new name of the category to rename
+ * @param int $p_assigned_to User ID that category is assigned to
+ * @return bool returns true or false depending on the success of the update action
+ */
+
+function mc_project_rename_category_by_name ($p_username, $p_password, $p_project_id, $p_category_name, $p_category_name_new, $p_assigned_to) {
+        $t_user_id = mci_check_login( $p_username, $p_password );
+
+        if ( null === $p_assigned_to ) {
+                return new soap_fault( 'Client', '', 'p_assigned_to needed' );
+        }
+
+        if( $t_user_id === false ) {
+                return new soap_fault( 'Client', '', 'Access Denied' );
+        }
+
+        if( !project_exists( $p_project_id ) ) {
+                return new soap_fault( 'Client', '', "Project '$p_project_id' does not exist." );
+        }
+
+        if( !mci_has_access( config_get( 'manage_project_threshold' ), $p_project_id ) ) {
+                return new soap_fault( 'Client', '', 'Access Denied' );
+        }
+
+        // find the id of the category
+        $p_category_id = category_get_id_by_name( $p_category_name, $p_project_id );
+
+        // update the category
+        return category_update( $p_category_id, $p_category_name_new, $p_assigned_to );
+}
+
+/**
  * Get all versions of a project.
  *
  * @param string $p_username  The name of the user trying to access the versions.
-- 
1.7.1


From 38ee884f4c81f4ca26a53b60d67ad51e5c19364d Mon Sep 17 00:00:00 2001
From: Franck Villaume <franck.villaume@capgemini.com>
Date: Mon, 3 May 2010 15:55:42 +0200
Subject: [PATCH 2/2] Add CategoryTest.php in loop for SOAP API test suite

Signed-off-by: Robert Munteanu <robert.munteanu@gmail.com>
---
 tests/soap/AllTests.php     |    2 +
 tests/soap/CategoryTest.php |  120 +++++++++++++++++++++++++++++++++++++++++++
 tests/soap/SoapBase.php     |    2 +-
 3 files changed, 123 insertions(+), 1 deletions(-)
 create mode 100644 tests/soap/CategoryTest.php

diff --git a/tests/soap/AllTests.php b/tests/soap/AllTests.php
index 988d948..c248675 100644
--- a/tests/soap/AllTests.php
+++ b/tests/soap/AllTests.php
@@ -33,6 +33,7 @@ require_once 'IssueUpdateTest.php';
 require_once 'FilterTest.php';
 require_once 'AttachmentTest.php';
 require_once 'LoginTest.php';
+require_once 'CategoryTest.php';
 
 /**
  * @package    Tests
@@ -63,6 +64,7 @@ class Soap_AllTests extends PHPUnit_Framework_TestSuite
         $suite->addTestSuite('FilterTest');
         $suite->addTestSuite('AttachmentTest');
         $suite->addTestSuite('LoginTest');
+        $suite->addTestSuite('CategoryTest');
 
         return $suite;
     }
diff --git a/tests/soap/CategoryTest.php b/tests/soap/CategoryTest.php
new file mode 100644
index 0000000..9e23bd5
--- /dev/null
+++ b/tests/soap/CategoryTest.php
@@ -0,0 +1,120 @@
+<?php
+# MantisBT - a php based bugtracking system
+
+# MantisBT is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 2 of the License, or
+# (at your option) any later version.
+#
+# MantisBT is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with MantisBT.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * @package Tests
+ * @subpackage UnitTests
+ * @copyright Copyright (C) 2010 MantisBT Team - mantisbt-dev@lists.sourceforge.net
+ * @link http://www.mantisbt.org
+ */
+
+require_once 'SoapBase.php';
+
+/**
+ * Test fixture for category webservice methods.
+ */
+class CategoryTest extends SoapBase {
+
+	private $categoryNamesToDelete = array();	
+
+	/**
+	 * A test case that tests the following:
+	 * 1. Get the project id.
+	 * 2. Add a category.
+	 * 3. Get the category list.
+	 * 4. Verify the category name in the list.
+	 * 5. Rename the category.
+	 * 6. Get the new category list
+	 * 7. Verify the cateogory name in the list
+	 * 8. Delete the category
+	 * 9. Verify the category is not in the list anymore
+	 */
+	public function testAddRenameDeleteCategory() {
+		$projectId = $this->getProjectId();
+		$categoryName = $this->getOriginalNameCategory();
+		$categoryNewName = $this->getNewNameCategory();
+
+		$categoryId = $this->client->mc_project_add_category(
+			$this->userName,
+			$this->password,
+			$projectId,
+			$categoryName);
+
+		$this->categoryNamesToDelete[] = $categoryName;
+			
+		$categoryList = $this->client->mc_project_get_categories(
+			$this->userName,
+			$this->password,
+			$projectId);
+
+		$this->assertContains($categoryName, $categoryList);
+
+		$return_bool = $this->client->mc_project_rename_category_by_name (
+			$this->userName,
+			$this->password,
+			$projectId,
+			$categoryName,
+			$categoryNewName,
+			'');
+
+		$this->categoryNamesToDelete = array( $categoryNewName );
+
+		$categoryList = $this->client->mc_project_get_categories(
+			$this->userName,
+			$this->password,
+			$projectId);
+
+		$this->assertNotContains($categoryName, $categoryList);
+		$this->assertContains($categoryNewName, $categoryList);
+
+		$return_bool = $this->client->mc_project_delete_category (
+			$this->userName,
+			$this->password,
+			$projectId,
+			$categoryNewName);
+
+		$this->categoryNamesToDelete = array() ;
+
+		$categoryList = $this->client->mc_project_get_categories(
+			$this->userName,
+			$this->password,
+			$projectId);
+
+		$this->assertNotContains($categoryNewName, $categoryList);
+	}
+
+	protected function tearDown() {
+
+		parent::tearDown();
+
+		foreach ( $this->categoryNamesToDelete as $categoryName )  {
+			$this->client->mc_project_delete_category(
+				$this->userName,
+				$this->password,
+				$this->getProjectId(),
+				$categoryName);
+		}
+	}
+    
+	private function getOriginalNameCategory() {
+ 		return 'my_category_name';
+	}
+    
+	private function getNewNameCategory() {
+ 		return 'my_new_category_name';
+	}
+ 
+}
diff --git a/tests/soap/SoapBase.php b/tests/soap/SoapBase.php
index 1c531bc..770b91b 100644
--- a/tests/soap/SoapBase.php
+++ b/tests/soap/SoapBase.php
@@ -71,7 +71,7 @@ class SoapBase extends PHPUnit_Framework_TestCase {
     protected function getCategory() {
  		return 'General';   	
     }
-    
+   
     protected function skipIfTimeTrackingIsNotEnabled() {
     	
     	$timeTrackingEnabled = $this->client->mc_config_get_string($this->userName, $this->password, 'time_tracking_enabled');
-- 
1.7.1

soap-categories.patch (12,453 bytes)   

Activities

rombert

rombert

2010-05-02 14:19

reporter   ~0025364

I took a cursory look at your patch and it looks good. Would you be willing to iterate on it a bit? I would be able to review and integrate the patch much faster if you would:

a) Submit Git patches ( see <a href="http://www.mantisforge.org/dev/manual/master/en/developers.html#DEV.CONTRIB">Contributing to MantisBT</a> );
b) Include a simple set of SOAP API tests ( see <a href="http://git.mantisbt.org/?p=mantisbt.git;a=blob;f=tests/soap/IssueNoteTest.php;h=ca1674362c70d3a85e85d7b00a9004b0dd1e08bc;hb=2b04a3a38d2352e33486433e1cb6399aa4aa4838">IssueNoteTest.php</a> for a sample).

Thanks,

Robert

nerville

nerville

2010-05-03 10:23

reporter   ~0025371

Hi,

I just uploaded a git patch file including a simple test for SOAP API.
As I'm not a git big fan nor user, I hope this will work.

Regards.

rombert

rombert

2010-05-03 16:42

reporter   ~0025381

This looks great!

I've set it up locally, and there are two minor changes I'd like to see before pushing to git:

1) Fixing the test:

[phpunit] testAddRenameDeleteCategory FAILED
[phpunit] Failed asserting that an array has the key <string:my_category_name>.
[phpunit] /home/robert/public_html/mantisbt/tests/soap/CategoryTest.php:56
[phpunit] /usr/share/php5/PEAR/phing.php:37

The contents of the array in my case is

Array
(
[0] => General
[1] => my_category_name
)

Perhaps you meant to lookup by value?

2) Cleaning up after creating a category in the test, ideally in a tearDown() function - see SoapBase for a sample. The test as such fails when run the second time.

Thanks once again.

nerville

nerville

2010-05-04 03:57

reporter   ~0025390

Hi,

1) you're right. My mistake.
I meant to lookup by value.
I upload a brand new patch to fix the test.

2) In my test, I delete the category created. I'm not sure if I need to create a tearDown function.

rombert

rombert

2010-05-06 07:12

reporter   ~0025418

Sorry about the delay, I was unable to reach mantisbt.org yesterday.

I suggested a tearDown method since if the test fails before the delete class, the category will not be deleted , and the tearDown method is the standard PHPUnit way. But feel free to do this any other way.

nerville

nerville

2010-05-06 08:11

reporter   ~0025420

I followed your suggestion and adapted my patch to comply with the PHPUnit standard way.

Regards.

rombert

rombert

2010-05-06 17:24

reporter   ~0025432

Thanks!

I've made some changes to your patches, namely:

  • prodded the test some more to make them stable;
  • rebased the tests patches into a single commit;
  • check if the user has manage_project_threshold before working with categories - this must be done, as otherwise it's a security issue.

Please confirm that the attached patch - based on master-1.2.x works fine for you. If it does, I will commit it.

nerville

nerville

2010-05-07 04:38

reporter   ~0025436

Hi,

currently, your patch does not work.

All calls to mci_has_access are :
if( !mci_has_access( config_get( 'manage_project_threshold' ), $p_project_id ) )

they should be :
if( !mci_has_access( config_get( 'manage_project_threshold' ), $t_user_id, $p_project_id ) )

except this, the patch is ok.
Regards.

rombert

rombert

2010-05-08 03:19

reporter   ~0025440

Good catch.

Fix applied and patch committed.

nerville

nerville

2010-05-12 08:14

reporter   ~0025485

Sounds like the mci_has_access calls are not fix everywhere.

It needs to be fix in line 154 and 191 in api/soap/mc_project_api.php file.
See my previous note.

Regards.

nerville

nerville

2010-05-12 08:15

reporter   ~0025486

The current situation does not allow the update or delete category.
mci_has_access calls are incomplete.

rombert

rombert

2010-05-12 12:38

reporter   ~0025488

Now fixed, sorry about the butter-fingers.

Related Changesets

MantisBT: master 8277d963

2010-05-12 12:36

rombert


Details Diff
Fix incorrect access checks for updating and deleting categories

Fixes 0011873: [patch] Add and delete category of a specific project using SOAP API
Affected Issues
0011873
mod - api/soap/mc_project_api.php Diff File

MantisBT: master-1.2.x 13b38c2b

2010-05-12 12:36

rombert


Details Diff
Fix incorrect access checks for updating and deleting categories

Fixes 0011873: [patch] Add and delete category of a specific project using SOAP API
Affected Issues
0011873
mod - api/soap/mc_project_api.php Diff File