CSC/ECE 517 Spring 2015/oss E1504 IMV
E1504. Refactoring the Bookmark Model
This page provides a description of the Expertiza based OSS project. This team project successfully refactored the Bookmark Model by removing the duplicate code, combining the methods, improving the search function, moving Bmapping model methods to their respective class, covering dependencies associated with changed segments and adding a User Interface for using bookmarks.
Introduction to Expertiza
Expertiza is a large project developed as a combined effort of students and faculty using the Ruby on Rails framework. The main advantage of using Expertiza, in an educational environment, is for the instructor to introduce peer reviewing among the students. Expertiza allows the instructor to create and customize assignments, create a list of topics the students can sign up for, have students work on teams and then review each other's assignments at the end. Expertiza supports submission of almost any document type, including the URLs and wiki pages.
Expertiza is supported by National Science Foundation under Grant No. 0536558. Additional funding from the NCSU Learning in a Technology-Rich Environment (LITRE) program, the NCSU Faculty Center for Teaching and Learning, the NCSU STEM Initiative, and the Center for Advanced Computing and Communication.
Problem Statement
Classes involved:
bookmark.rb bmapping.rb bookmarks_controller.rb auth_controller.rb auth_helper.rb
What they do: The bookmark model and controller work together to create and maintain user specific bookmarks, which can be added to different topics. Moreover, the user that created a bookmark can use his privilege to edit it at a later point in time. As a functionality added for convenience, any user can search bookmarks by either users who created them or their bookmark tags.
What needs to be done:
- The search methods in bookmarks model are being used used on a very granular level. This led to redundancy in bookmarks search methods. These methods include search_alltags_allusers, search_fortags_allusers, search_fortags_forusers, search_alltags_forusers. Hence duplicates in these methods are to be singled out.
- Following the CRUD declaration in Ruby on Rails, where the method name should specify the pseudo use of itself,methods such as add_new_bookmark and edit_this_bookmark have violate this naming convention. Therefore, we need to change the names of these two methods to create and edit, respectively. Upon changing the names, all the dependencies need to be updated, as well.
- Refactor add_topic_bookmark and add_this_bookmark by removing the repetitive code. These two methods differ only in 2 lines of code, which make it reasonable to merge them together into a single method that provides functionality of both individual methods.
- Fix the bug in add_bookmark method where only bookmarks without topic_id can be properly created. We add the functionality to this method to allow it to also create bookmarks with provided topic_id.
- Methods add_bmapping and add_bmapping_signuptopic need to be moved to their appropriate model (Bmapping model) rather than reside in Bookmarks model. Completing this task involves checking the dependencies and updating the function calls for these methods, accordingly.
- Add user interface for Bookmarks as this functionality has not been a part of Expertiza
- Create a functional tests suite covering the functionality of all the methods that have been changed by our team.
- Create a Cucumber integration test to show the functionality of added user interface for Bookmarks.
Changes Made
Bookmark Model
Method Name | Changes Made | Reason For Change |
---|---|---|
add_this_bookmark | Added functionality of add_topic_bookmark | To implement code reusability and remove repetitive code. |
add_topic_bookmark | Merged the functionality into add_this_bookmarks and deleted add_topic_bookmark | To implement code reusability and remove repetitive code. |
add_bookmark | Added a line that checks whether topic_id has been provided in the request | It allows creation of new Bmapping if no topic_id was given and removes the bug of searching for bookmark with nil topic_id later on |
search_alltags_allusers | Merged search_alltags_allusers and search_alltags_foruser functions into search_alltags | Duplicate code present in both the functions. They differed only with the usage of parameters passed. |
search_alltags_foruser | Merged search_alltags_allusers and search_alltags_foruser functions into search_alltags function | Duplicate code present in both the functions. They differed only with the usage of parameters passed. |
search_fortags_allusers | Merged search_fortags_allusers and search_fortags_foruser functions into search_fortags function | Duplicate code present in both the functions. They differed only with the usage of parameters passed. |
search_fortags_foruser | Merged search_fortags_allusers and search_fortags_foruser functions into search_fortags function | Duplicate code present in both the functions. They differed only with the usage of parameters passed. |
add_new_bookmark | Changed the method name to "create" | It is a much more meaningful and simpler name for a method that creates a new bookmark |
edit_this_bookmark | Changed the name to "edit" | It is a much more appropriate name for a method that edits the bookmark it was called on |
add_bmapping | Moved to class 'Bmapping' | This method helps in creating new bmapping. Hence it makes more sense if it belongs to bmapping class itself. |
add_bmapping_signuptopic | Moved to class 'Bmapping' | This method helps in adding a signup topic to a newly created bmapping. Hence it makes more sense if it belongs to bmapping class itself. |
Bookmark Controller
Method Name | Changes Made | Reason For Change |
---|---|---|
create | ---------------- | ----------- |
update | ----------------- | -------- |
edit | -------------- | --------- |
destroy |
----------------- | --------- |
--------------- | ---------- | |
---------- | ---------- |
Views
Method Name | Changes Made | Reason For Change |
---|---|---|
bookmarks/_result.html.erb | ---------------- | ----------- |
bookmarks/search_bookmarks.html.erb | ----------------- | -------- |
bookmarks/view_bookmarks.html.erb | -------------- | --------- |
bookmarks/_searchmine.html.erb | ----------------- | --------- |
bookmarks/add_bookmark_form.html.erb | ----------------- | --------- |
bookmarks/edit_bookmark_form.html.erb | ----------------- | --------- |
bookmarks/managing_bookmarks.html.erb | ----------------- | --------- |
layouts/application.html.erb | ----------------- | --------- |
tree_display/list.html.erb | added a link to Manage Bookmarks page | This allows a user to see the link to Managing Bookmarks page as soon as the user logs in. |
Re-factored Code Cases
Case 1 : Refactoring add_this_bookmark and add_topic_bookmark
The consistency of these two methods shows plenty of repetitive code. In order to effectively refactor these methods and reuse the code they both need, our team merged the two methods together by enabling add_this_bookmark method to handle creation of a bookmark when a topic id is provided (main functionality of add_topic_bookmark method). Once we implemented this change on add_this_bookmark method, we deleted add_topic_bookmark method as it became obsolete. Therefore, we retained the same functionality while reducing the method by 7 repetitive lines of code.
Before Changes
Please note that these two methods only differ in a single line of code (line 6 and 16) where line 6 takes an extra parameter (topic_id).
1: def self.add_topic_bookmark(b_url, b_title, b_tags_text, b_description,session_user, topicid) 2: # Check if the bookmark exists and add / edit based on that 3: bookmark_exists = check_bookmark_exists(b_url) 4: bmapping_exists = check_bmapping_exists(b_url,session_user) 5: if (!bookmark_exists || !bmapping_exists) 6: Bookmark.add_bookmark(b_url, b_title, b_tags_text, b_description,session_user,topicid) 7: elsif (bmapping_exists) 8: Bookmark.edit_this_bookmark(b_url, b_title, b_tags_text, b_description,session_user) 9: end 10: end 11: 12: def self.add_this_bookmark(b_url, b_title, b_tags_text, b_description,session_user) 13: bookmark_exists = check_bookmark_exists(b_url) 14: bmapping_exists = check_bmapping_exists(b_url,session_user) 15: if (!bookmark_exists || !bmapping_exists) 16: Bookmark.add_bookmark(b_url, b_title, b_tags_text, b_description,session_user) 17: elsif (bmapping_exists) 18: Bookmark.edit_this_bookmark(b_url, b_title, b_tags_text, b_description,session_user) 19: end 20: end
After Changes
1: def self.add_this_bookmark(b_url, b_title, b_tags_text, b_description,session_user, topic_id) 2: bookmark_exists = check_bookmark_exists(b_url) 3: bmapping_exists = check_bmapping_exists(b_url,session_user) 4: if (!bookmark_exists || !bmapping_exists) 5: if(topic_id) # something has been passed for topic_id 6: Bookmark.add_bookmark(b_url, b_title, b_tags_text, b_description,session_user,topic_id) 7: else 8: Bookmark.add_bookmark(b_url, b_title, b_tags_text, b_description,session_user, nil) 9: end 10: elsif (bmapping_exists) 11: Bookmark.edit(b_url, b_title, b_tags_text, b_description,session_user) 12: end 13: end
Case 2 : Fixing a bug in add_bookmark method
Our team fixed the bug associate with topic_id nil being provided to add_bookmark method (user has not specified topic_id) when creating a bookmark. We include an if statement that calls add_bmapping_signuptopic method only if the provided topic_id is not nil. This change has been implemented on line 9 in the code block shown bellow.
Change on line 9
# Adds a bookmark and its various associations def self.add_bookmark(b_url, b_title, b_tags_text, b_description,session_user,topic_id) bookmark_resource = Bookmark.where(["url = ?",b_url]).first # Bookmark with the same url does not exists. if bookmark_resource.nil? # Add the newly discovered bookmark bookmarkid = create(b_url,session_user.id) # Add its associations to a user bmappingid = Bmapping.add_bmapping(bookmarkid, b_title, session_user.id, b_description,b_tags_text ) 9: if(!topic_id.nil?) # Add its association to the sign up topic if the topic was provided Bmapping.add_bmapping_signuptopic(topic_id, bmappingid) end # Bookmark with the same url exists. else bmapping = Bmapping.where(bookmark_id: bookmark_resource.id, user_id: session_user.id).first # Bookmark with the same user - bmapping exists. if ( !bmapping.nil? ) topic = SignUpTopic.find(topic_id) if( !topic.nil? ) topic.bmappings.each do |mapping| if (mapping.id == bmapping.id) Bookmark.edit(b_url, b_title, b_tags_text, b_description,session_user) end end # Signup Topic does not exists else Bmapping.add_bmapping_signuptopic(topic_id, bmapping.id) end # Bookmark with same user - bmapping does not exists. else # Increment user count for the existing bookmark bookmark_resource.user_count = bookmark_resource.user_count + 1 bookmark_resource.save # Add its association with the user bmappingid = Bmapping.add_bmapping(bookmark_resource.id, b_title, session_user.id, b_description,b_tags_text) Bmapping.add_bmapping_signuptopic(topic_id, bmappingid) end end end
Case 3 : Refactoring search_fortags_allusers and search_fortags_forusers
Both these methods contain almost the same code except for few conditional lines. search_fortags_allusers searches for all tags for all users whereas search_fortags_forusers searches only for those tags that belong to the user. The code for both these functions differed only in the query clause where at one place it checks for records returned for a specific user and at the other place, it does not have this check.
Before Changes
search_fortags_allusers function (topic_id).
def self.search_fortags_allusers(tags_array, order_by) result_array = Array.new # returns this array ## find the tags associated with these tagnames @tags = BookmarksHelper.find_tags(tags_array) @q_tuples_with_all_tags = Array.new ## retreive mapping_ids taggeed with all of the word tags ## for every word, search for every bookmark that was tagged with that word. Then take the intersection of all the bmapping_ids first_time = "true" for each_tag in @tags q_tuples = BmappingsTags.where(["tag_id = ?", each_tag]) if first_time == "true" for q_t in q_tuples @q_tuples_with_all_tags << q_t.bmapping_id end first_time = "false" else temp_array = Array.new for q_t in q_tuples temp_array << q_t.bmapping_id end @q_tuples_with_all_tags = @q_tuples_with_all_tags & temp_array ## returns the items common to both arrays end end ## now you have qualifer tuples with all the required bmapping ids - search for the req ones temp_result_records = Bmapping.where(["id in (?)", @q_tuples_with_all_tags]) result_records = Array.new ## organize these tuples in the order of most earliest, most popular if (order_by =="most_recent") result_records = temp_result_records.sort {|x,y| y.date_created <=> x.date_created} else result_records = temp_result_records.sort {|x,y| y.bookmark.user_count <=> x.bookmark.user_count } end ## for evey bmapping_id, create a hash, and push into the result_array for result in result_records result_hash = Hash.new result_hash["id"] = result.id result_hash["url"] = result.bookmark.url result_hash["created_at"] = result.date_created result_hash["user"] = result.user.name result_hash["title"] = result.title result_hash["description"] = result.description result_hash["copied_by"] = result.bookmark.user_count ## now retrieving tags for this user-bookmak mapping ## first retrieve all the tag_ids mapped to the BMapping id. Then retrieve all the tag names of the tag_ids picked up. ## Append all these into a comma separated string, and push them onto the hash tag_fetchs = BmappingsTags.where(["bmapping_id =?",result.id]) tag_array = Array.new for tag_fetch in tag_fetchs tag_array << Tag.find(tag_fetch.tag_id).tagname end result_hash["tags"] = BookmarksHelper.join_tags(tag_array) result_array << result_hash end return result_array end
Before Changes
search_fortags_foruser
def self.search_fortags_foruser(tags_array, this_user_id, order_by) #order by is in "most_popular" and "most_recent" result_array = Array.new ## search for ids of the tags @tags = BookmarksHelper.find_tags(tags_array) @q_tuples_with_all_tags = Array.new first_time = "true" for each_tag in @tags ##search for all qualifier tuples with b q_tuples = BmappingsTags.where(["tag_id = ?", each_tag]) #for q_t in q_tuples #end if first_time == "true" for q_t in q_tuples @q_tuples_with_all_tags << q_t.bmapping_id end first_time = "false" else temp_array = Array.new for q_t in q_tuples temp_array << q_t.bmapping_id end @q_tuples_with_all_tags = @q_tuples_with_all_tags & temp_array ## returns the items common to both arrays end end ## now you have qualifer tuples with all the required bmapping ids - search for the req ones temp_result_records = Bmapping.where(["id in (?) and user_id = ?", @q_tuples_with_all_tags,this_user_id ]) ## organize these tuples in the order of most earliest, most popular result_records = Array.new if (order_by == "most_recent") result_records = temp_result_records.sort {|x,y| y.date_created <=> x.date_created} else result_records = temp_result_records.sort {|x,y| y.bookmark.user_count <=> x.bookmark.user_count } end for result in result_records result_hash = Hash.new result_hash["id"] = result.id result_hash["url"] = result.bookmark.url result_hash["user"] = User.find(this_user_id).name result_hash["title"] = result.title result_hash["description"] = result.description result_hash["copied_by"] = result.bookmark.user_count result_hash["created_at"] = result.date_created ## now retrieving tags for this user-bookmak mapping ## first retrieve all the tag_ids mapped to the BMapping id. Then retrieve all the tag names of the tag_ids picked up. ## Append all these into a comma separated string, and push them onto the hash tag_fetchs = BmappingsTags.where(["bmapping_id=?",result.id]) tag_array = Array.new for tag_fetch in tag_fetchs tag_array << Tag.find(tag_fetch.tag_id).tagname end result_hash["tags"] = BookmarksHelper.join_tags(tag_array) result_array << result_hash end return result_array end
After Changes
The above two functions are merged into a single function named "search_fortags function" as shown below.
## searches for tspecified tags, among a specified user, orders them by most popular and the most recently added def self.search_fortags(tags_array, order_by,this_user_id) #order by is in "most_popular" and "most_recent" result_array = Array.new ## search for ids of the tags @tags = BookmarksHelper.find_tags(tags_array) @q_tuples_with_all_tags = Array.new first_time = "true" for each_tag in @tags ##search for all qualifier tuples with b q_tuples = BmappingsTag.where(["tag_id = ?", each_tag]) #if first_time == "true" for q_t in q_tuples @q_tuples_with_all_tags << q_t.bmapping_id end #first_time = "false" # else # temp_array = Array.new # for q_t in q_tuples # temp_array << q_t.bmapping_id # end # @q_tuples_with_all_tags = @q_tuples_with_all_tags & temp_array ## returns the items common to both arrays # end end if(this_user_id != nil) ## now you have qualifer tuples with all the required bmapping ids and the requested userid- search for the req ones temp_result_records = Bmapping.where(["id in (?) and user_id = ?", @q_tuples_with_all_tags, this_user_id ]) else ## now you have qualifer tuples with all the required bmapping ids - search for the req ones temp_result_records = Bmapping.where(["id in (?)", @q_tuples_with_all_tags]) end ## organize these tuples in the order of most earliest, most popular result_records = Array.new if (order_by == "most_recent") result_records = temp_result_records.sort {|x,y| y.date_created <=> x.date_created} else result_records = temp_result_records.sort {|x,y| y.bookmark.user_count <=> x.bookmark.user_count } end for result in result_records result_hash = Hash.new result_hash["id"] = result.id result_hash["url"] = result.bookmark.url result_hash["user"] = result.user.name result_hash["title"] = result.title result_hash["description"] = result.description result_hash["copied_by"] = result.bookmark.user_count result_hash["created_at"] = result.date_created ## now retrieving tags for this user-bookmak mapping ## first retrieve all the tag_ids mapped to the BMapping id. Then retrieve all the tag names of the tag_ids picked up. ## Append all these into a comma separated string, and push them onto the hash tag_fetchs = BmappingsTag.where(["bmapping_id=?",result.id]) tag_array = Array.new for tag_fetch in tag_fetchs tag_array << Tag.find(tag_fetch.tag_id).tagname end result_hash["tags"] = BookmarksHelper.join_tags(tag_array) result_array << result_hash end return result_array end
Before Changes
The below is the "search_alltags_foruser" function from the bookmark model before the changes were made.
def self.search_alltags_foruser (the_userid, order_by) result_array = Array.new #going to append all the results into this array if(order_by == "most_recent" ) ## find all the bmappings in this system, created by this user, order them by the date created. # For each tuple returned from the bmapping, generate a hash, containing the url, the specified user's name, date this mapping was made, ## title, and description provided by this user. Store these hashes sequentially in a array ad return the array result_records = Bmapping.where([" user_id = ?", the_userid]).order("date_created DESC").limit(20) for result in result_records result_hash = Hash.new result_hash["id"] = result.id result_hash["url"] = result.bookmark.url result_hash["user"] = User.find(the_userid).name result_hash["created_at"] = result.date_created result_hash["title"] = result.title result_hash["description"] = result.description result_hash["copied_by"] = result.bookmark.user_count ## now retrieving tags for this user-bookmak mapping ## first retrieve all the tag_ids mapped to the BMapping id. Then retrieve all the tag names of the tag_ids picked up. ## Append all these into a comma separated string, and push them onto the hash tag_fetchs = BmappingsTags.where(["bmapping_id = ?",result.id]) tag_array = Array.new for tag_fetch in tag_fetchs tag_array << Tag.find(tag_fetch.tag_id).tagname end result_hash["tags"] = BookmarksHelper.join_tags(tag_array) result_array << result_hash end elsif ( order_by == "most_popular") ### retrieving the most popular records that this user.(The user need not be the discoverer). First retrieve the the user's bookmarks from the bmapping. ### order these records, based on the user_count of the url temp_result_records = Bmapping.where([" user_id = ?", the_userid]) ## order result records by result.user_count a.sort {|x,y| y <=> x } result_records = temp_result_records.sort {|x,y| y.bookmark.user_count <=> x.bookmark.user_count} for result in result_records result_hash = Hash.new result_hash["url"] = result.bookmark.url result_hash["id"] = result.id result_hash["user"] = User.find(the_userid).name result_hash["title"] = result.title result_hash["description"] = result.description result_hash["copied_by"] = result.bookmark.user_count ## now retrieving tags for this user-bookmak mapping ## first retrieve all the tag_ids mapped to the BMapping id. Then retrieve all the tag names of the tag_ids picked up. ## Append all these into a comma separated string, and push them onto the hash tag_fetchs = BmappingsTags.where(["bmapping_id = ?",result.id]) tag_array = Array.new for tag_fetch in tag_fetchs tag_array << Tag.find(tag_fetch.tag_id).tagname end result_hash["tags"] =BookmarksHelper.join_tags(tag_array) result_array << result_hash end end return result_array end
Before Changes
The below is the "search_alltags_allusers" before the changes were made.
def self.search_alltags_allusers(order_by) result_array = Array.new #going to append all the results into this array if(order_by == "most_recent") ## find all the records in the system, order them by the date created. Using Bmapping here. Returns mappings that where created most recently, ## the user that created this mapping, the title and description provided this user result_records = Bmapping.all(:order =>"date_created DESC", :limit =>20) for result in result_records ## for each tuple returned by the query above, create a new hash, store the values appropriately, and append into the return_array result_hash = Hash.new result_hash["id"] = result.id result_hash["url"] = result.bookmark.url result_hash["user"] = result.user.name # displaying the newest owner of the bookmark, result_hash["title"] = result.title result_hash["created_at"] = result.date_created result_hash["description"] = result.description result_hash["copied_by"] = result.bookmark.user_count ## number of people having this user in their repository ## now retrieving tags for this user-bookmak mapping ## first retrieve all the tag_ids mapped to the BMapping id. Then retrieve all the tag names of the tag_ids picked up. ## Append all these into a comma separated string, and push them onto the hash tag_fetchs = BmappingsTags.where(["bmapping_id = ?",result.id]) tag_array = Array.new for tag_fetch in tag_fetchs tag_array << Tag.find(tag_fetch.tag_id).tagname end result_hash["tags"] = BookmarksHelper.join_tags(tag_array) result_array << result_hash end elsif (order_by == "most_popular") ## returns the url boomarked by the most number of users, the discoverer of that url, the title and description provided by the discoverer result_records = Bookmark.all(:order =>"user_count DESC", :limit =>20) for result in result_records ## for each tuple returned by the query above, create a new hash, store the values appropriately, and append into the return_array result_hash = Hash.new result_hash["url"] = result.url result_hash["user"] = User.find(result.discoverer_user_id).name result_hash["copied_by"] = result.user_count b_u_mapping = Bmapping.where(["bookmark_id = ? and user_id = ?", result.id, result.discoverer_user_id]).first result_hash["id"] = b_u_mapping.id result_hash["description"] = b_u_mapping.description result_hash["title"] = b_u_mapping.title ## now retrieving tags for this user-bookmak mapping ## first retrieve all the tag_ids mapped to the BMapping id. Then retrieve all the tag names of the tag_ids picked up. ## Append all these into a comma separated string, and push them onto the hash tag_fetchs = BmappingsTags.where(["bmapping_id = ?",b_u_mapping.id]) tag_array = Array.new for tag_fetch in tag_fetchs tag_array << Tag.find(tag_fetch.tag_id).tagname end result_hash["tags"] = BookmarksHelper.join_tags(tag_array) result_array << result_hash end end return result_array end
After Changes
The above two functions were merged into a single function "search_alltags" as shown below:
def self.search_alltags (the_userid, order_by) result_array = Array.new #going to append all the results into this array if(order_by == "most_recent" ) ## find all the bmappings in this system, created by this user, order them by the date created. # For each tuple returned from the bmapping, generate a hash, containing the url, the specified user's name, date this mapping was made, ## title, and description provided by this user. Store these hashes sequentially in a array ad return the array if(the_userid == nil) ## find all the records in the system, order them by the date created. Using Bmapping here. Returns mappings that where created most recently, ## the user that created this mapping, the title and description provided this user result_records = Bmapping.all.order("date_created DESC").limit(20) else result_records = Bmapping.where([" user_id = ?", the_userid]).order("date_created DESC").limit(20) end #result_records = Bmapping.where([" user_id = ?", the_userid]).order("date_created DESC").limit(20) for result in result_records result_hash = Hash.new result_hash["id"] = result.id result_hash["url"] = result.bookmark.url result_hash["user"] = result.user.name result_hash["created_at"] = result.date_created result_hash["title"] = result.title result_hash["description"] = result.description result_hash["copied_by"] = result.bookmark.user_count ## now retrieving tags for this user-bookmak mapping ## first retrieve all the tag_ids mapped to the BMapping id. Then retrieve all the tag names of the tag_ids picked up. ## Append all these into a comma separated string, and push them onto the hash tag_fetchs = BmappingsTag.where(["bmapping_id = ?",result.id]) tag_array = Array.new for tag_fetch in tag_fetchs tag_array << Tag.find(tag_fetch.tag_id).tagname end result_hash["tags"] = BookmarksHelper.join_tags(tag_array) result_array << result_hash end elsif ( order_by == "most_popular" and the_userid != nil) ### retrieving the most popular records that this user.(The user need not be the discoverer). First retrieve the the user's bookmarks from the bmapping. ### order these records, based on the user_count of the url temp_result_records = Bmapping.where([" user_id = ?", the_userid]) ## order result records by result.user_count a.sort {|x,y| y <=> x } result_records = temp_result_records.sort {|x,y| y.bookmark.user_count <=> x.bookmark.user_count} for result in result_records result_hash = Hash.new result_hash["url"] = result.bookmark.url result_hash["id"] = result.id result_hash["user"] = User.find(the_userid).name result_hash["title"] = result.title result_hash["description"] = result.description result_hash["copied_by"] = result.bookmark.user_count ## now retrieving tags for this user-bookmak mapping ## first retrieve all the tag_ids mapped to the BMapping id. Then retrieve all the tag names of the tag_ids picked up. ## Append all these into a comma separated string, and push them onto the hash tag_fetchs = BmappingsTag.where(["bmapping_id = ?",result.id]) tag_array = Array.new for tag_fetch in tag_fetchs tag_array << Tag.find(tag_fetch.tag_id).tagname end result_hash["tags"] =BookmarksHelper.join_tags(tag_array) result_array << result_hash end elsif (order_by == "most_popular" and the_userid == nil) ## returns the url boomarked by the most number of users, the discoverer of that url, the title and description provided by the discoverer result_records = Bookmark.all(:order =>"user_count DESC", :limit =>20) for result in result_records ## for each tuple returned by the query above, create a new hash, store the values appropriately, and append into the return_array result_hash = Hash.new result_hash["url"] = result.url result_hash["user"] = User.find(result.discoverer_user_id).name result_hash["copied_by"] = result.user_count b_u_mapping = Bmapping.where(["bookmark_id = ? and user_id = ?", result.id, result.discoverer_user_id]).first result_hash["id"] = b_u_mapping.id result_hash["description"] = b_u_mapping.description result_hash["title"] = b_u_mapping.title ## now retrieving tags for this user-bookmak mapping ## first retrieve all the tag_ids mapped to the BMapping id. Then retrieve all the tag names of the tag_ids picked up. ## Append all these into a comma separated string, and push them onto the hash tag_fetchs = BmappingsTag.where(["bmapping_id = ?",b_u_mapping.id]) tag_array = Array.new for tag_fetch in tag_fetchs tag_array << Tag.find(tag_fetch.tag_id).tagname end result_hash["tags"] = BookmarksHelper.join_tags(tag_array) result_array << result_hash end end return result_array end
Steps to verify changes manually
User2 Role
In order to inspect the changes made to the bookmark mode manually, you can use the following credentials:
User Name: user2 Password: any password
As you can notice in the credentials above, you can type in any password you wish in order to log in as user2. We have accomplished this by disabling the authentication and the reason behind it was to have an easily reachable user account for test and development purposes.
The below screenshots demonstrate the working of search features .
Automated Tests
Functional test suite
We have developed a suit of extensive unit tests covering all the functionality that we have add/modified in the forked version of Expertiza. The test suite consists of 9 tests providing 14 assertions that cover the functionality of all the method changes described in the former sections of this wiki page. The source code for these tests is stored in test/models/bookmark_test.rb file. You can run this test suite by simply navigating to expertiza project directory and running command:
ruby -I test test/models/bookmark_test.rb
Integration (Cucumber) tests
In addition to functional tests, we have also provided a Cucumber test as an integration test. The goal of this test is to show that a user can access the Manage Bookmarks page upon successful log in, proving that bookmarks view have been successfully integrated into expertiza system. The construct of this test can be found in following files:
features/bookmark.feature features/step_definitions/bookmark_steps
To run this cucumber test, please navigate to expertiza project directory and run the following command:
rake cucumber