Example #1
0
    def test_delete_milestone(self):
        self.env.db_transaction("INSERT INTO milestone (name) VALUES ('Test')")

        milestone = Milestone(self.env, "Test")
        milestone.delete()
        self.assertEqual(False, milestone.exists)
        self.assertEqual([], self.env.db_query("SELECT * FROM milestone WHERE name='Test'"))
Example #2
0
 def testBacklogForMultipleSprint(self):
     """Tests a Backlog associated to a Sprint with multiple sprints"""
     # Creates a Milestone
     m = Milestone(self.env)
     m.name = "Milestone 1"
     m.insert()
     # Create 2 Sprints
     sprint1 = self.teh.create_sprint(name="Sprint 1", start=to_datetime(t=None), duration=20, milestone=m.name)
     sprint2 = self.teh.create_sprint(name="Sprint 2", start=to_datetime(t=None), duration=20, milestone=m.name)
     # Create some tickets
     s1 = self.teh.create_ticket(Type.USER_STORY, props={Key.STORY_POINTS: "3", Key.SPRINT: sprint1.name})
     self.assert_true(
         s1.link_to(self.teh.create_ticket(Type.TASK, props={Key.REMAINING_TIME: "4", Key.SPRINT: sprint1.name}))
     )
     self.assert_true(
         s1.link_to(self.teh.create_ticket(Type.TASK, props={Key.REMAINING_TIME: "8", Key.SPRINT: sprint1.name}))
     )
     self.assert_true(s1.link_to(self.teh.create_ticket(Type.TASK, props={Key.REMAINING_TIME: "4"})))
     s2 = self.teh.create_ticket(Type.USER_STORY, props={Key.STORY_POINTS: "5", Key.SPRINT: sprint2.name})
     self.assert_true(
         s2.link_to(self.teh.create_ticket(Type.TASK, props={Key.REMAINING_TIME: "2", Key.SPRINT: sprint2.name}))
     )
     self.assert_true(s2.link_to(self.teh.create_ticket(Type.TASK, props={Key.REMAINING_TIME: "3"})))
     # Creates the Backlog bound to the Sprint
     backlog = BacklogConfiguration(self.env, name="Sprint-Backlog", type=BacklogType.SPRINT)
     backlog.ticket_types = [Type.USER_STORY, Type.TASK]
     backlog.save()
     # The Backlog should contains only the items planned for the Sprint, and with parents
     # planned for the Sprint too
     backlog1 = self.bmm.get(name="Sprint-Backlog", scope=sprint1.name)
     self.assert_length(3, backlog1)
     backlog2 = self.bmm.get(name="Sprint-Backlog", scope=sprint2.name)
     self.assert_length(2, backlog2)
Example #3
0
    def process_request(self, req):
        milestone_id = req.args.get("id")
        req.perm("milestone", milestone_id).require("MILESTONE_VIEW")

        add_link(req, "up", req.href.roadmap(), _("Roadmap"))

        action = req.args.get("action", "view")
        try:
            milestone = Milestone(self.env, milestone_id)
        except ResourceNotFound:
            if "MILESTONE_CREATE" not in req.perm("milestone", milestone_id):
                raise
            milestone = Milestone(self.env, None)
            milestone.name = milestone_id
            action = "edit"  # rather than 'new' so that it works for POST/save

        if req.method == "POST":
            if req.args.has_key("cancel"):
                if milestone.exists:
                    req.redirect(req.href.milestone(milestone.name))
                else:
                    req.redirect(req.href.roadmap())
            elif action == "edit":
                return self._do_save(req, milestone)
            elif action == "delete":
                self._do_delete(req, milestone)
        elif action in ("new", "edit"):
            return self._render_editor(req, milestone)
        elif action == "delete":
            return self._render_confirm(req, milestone)

        if not milestone.name:
            req.redirect(req.href.roadmap())

        return self._render_view(req, milestone)
Example #4
0
def copy_milestone(source_env, dest_env, name, dest_db=None):
    # In case a string gets passed in
    if not isinstance(source_env, Environment):
        source_env = _open_environment(source_env)
    if not isinstance(dest_env, Environment):
        dest_env = _open_environment(dest_env)

    # Log message
    source_env.log.info("DatamoverPlugin: Moving milestone %s to the environment at %s", name, dest_env.path)
    dest_env.log.info("DatamoverPlugin: Moving milestone %s from the environment at %s", name, source_env.path)

    # Open databases
    source_db = source_env.get_db_cnx()
    source_cursor = source_db.cursor()
    handle_commit = True
    if not dest_db:
        dest_db, handle_commit = dest_env.get_db_cnx(), False
    dest_cursor = dest_db.cursor()

    # Remove the milestone from the destination
    try:
        dest_milestone = Milestone(dest_env, name, db=dest_db)
        dest_milestone.delete(retarget_to=name, db=dest_db)
    except TracError:
        pass

    # Copy each entry in the milestone table
    source_cursor.execute("SELECT * FROM milestone WHERE name=%s", (name,))
    for row in source_cursor:
        milestone_data = dict(zip([d[0] for d in source_cursor.description], row))
        q = make_query(milestone_data, "milestone")
        dest_cursor.execute(*q)

    if handle_commit:
        dest_db.commit()
Example #5
0
    def test_update_milestone_without_name(self):
        cursor = self.db.cursor()
        cursor.execute("INSERT INTO milestone (name) VALUES ('Test')")
        cursor.close()

        milestone = Milestone(self.env, "Test")
        milestone.name = None
        self.assertRaises(TracError, milestone.update)
Example #6
0
    def test_create_milestone(self):
        milestone = Milestone(self.env)
        milestone.name = "Test"
        milestone.insert()

        cursor = self.db.cursor()
        cursor.execute("SELECT name,due,completed,description FROM milestone " "WHERE name='Test'")
        self.assertEqual(("Test", 0, 0, ""), cursor.fetchone())
Example #7
0
 def ticket_changed(self, ticket, comment, author, old_values):
     old_summary = old_values.get("summary")
     if ticket["type"] == milestone_ticket_type and old_summary and ticket["summary"] != old_summary:
         try:
             milestone = Milestone(self.env, old_summary)
             if milestone.exists:
                 milestone.name = ticket["summary"]
                 milestone.update()
         except ResourceNotFound:
             pass
Example #8
0
    def test_delete_milestone(self):
        cursor = self.db.cursor()
        cursor.execute("INSERT INTO milestone (name) VALUES ('Test')")
        cursor.close()

        milestone = Milestone(self.env, "Test")
        milestone.delete()

        cursor = self.db.cursor()
        cursor.execute("SELECT * FROM milestone WHERE name='Test'")
        self.assertEqual(None, cursor.fetchone())
Example #9
0
def milestone_setup(tc):
    from datetime import datetime
    from trac.util.datefmt import utc

    boo = Milestone(tc.env)
    boo.name = "boo"
    boo.completed = boo.due = None
    boo.insert()
    roo = Milestone(tc.env)
    roo.name = "roo"
    roo.completed = datetime.now(utc)
    roo.due = None
    roo.insert()
Example #10
0
File: api.py Project: pkdevbox/trac
    def test_get_ticket_fields_milestone_rename(self):
        """Cached ticket fields are updated when milestone is renamed."""
        fields = self.ticket_system.get_ticket_fields()
        milestone_field = self._get_ticket_field("milestone")
        m2 = Milestone(self.env, "milestone2")
        m2.name = "milestone5"

        m2.update()
        updated_fields = self.ticket_system.get_ticket_fields()
        updated_milestone_field = self._get_ticket_field("milestone")

        self.assertNotEqual(fields, updated_fields)
        self.assertEqual(["milestone1", "milestone2", "milestone3", "milestone4"], milestone_field["options"])
        self.assertEqual(["milestone1", "milestone3", "milestone4", "milestone5"], updated_milestone_field["options"])
    def _go_graph(self, req):
        # search all artifacts.
        artifacts = ArtifactManager.find_all(self.env)

        milestones = [m for m in Milestone.select(self.env) if "MILESTONE_VIEW" in req.perm(m.resource)]

        # add artifacts to milestone.
        for m in milestones:
            artifacts_of_m = [artifact for artifact in artifacts if artifact.milestone == m.name]
            setattr(m, "artifacts", artifacts_of_m)

        manager = SCMManager(self.env, req)
        nodes = manager.artifacts_to_nodes(artifacts)

        roots = manager.get_roots(nodes)

        gm = GraphManager(self.env)
        nodes = gm.to_graphnode(roots)

        gm.to_s(nodes)

        graph = gm.to_graphviz(nodes, milestones)

        self.env.log.info("graphviz graph:\n%s" % graph)

        data = {"milestones": milestones, "artifacts": artifacts, "graph": graph}
        return "releaseartifactgraph.html", data, None
Example #12
0
 def _modify_roadmap_page(self, req, template, data, content_type, is_active):
     """Insert roadmap.css + products breadcrumb
     """
     add_stylesheet(req, "dashboard/css/roadmap.css")
     self._add_products_general_breadcrumb(req, template, data, content_type, is_active)
     data["milestone_list"] = [m.name for m in Milestone.select(self.env)]
     req.chrome["ctxtnav"] = []
Example #13
0
    def test_delete_milestone_retarget_tickets(self):
        self.env.db_transaction("INSERT INTO milestone (name) VALUES ('Test')")

        tkt1 = Ticket(self.env)
        tkt1.populate({"summary": "Foo", "milestone": "Test"})
        tkt1.insert()
        tkt2 = Ticket(self.env)
        tkt2.populate({"summary": "Bar", "milestone": "Test"})
        tkt2.insert()

        milestone = Milestone(self.env, "Test")
        milestone.delete(retarget_to="Other")
        self.assertEqual(False, milestone.exists)

        self.assertEqual("Other", Ticket(self.env, tkt1.id)["milestone"])
        self.assertEqual("Other", Ticket(self.env, tkt2.id)["milestone"])
Example #14
0
File: api.py Project: pkdevbox/trac
    def test_get_ticket_fields_milestone_update_due(self):
        """Cached ticket fields are updated when milestone due date is
        changed.
        """
        fields = self.ticket_system.get_ticket_fields()
        milestone_field = self._get_ticket_field("milestone")
        m2 = Milestone(self.env, "milestone2")
        m2.due = datetime.now(utc)

        m2.update()
        updated_fields = self.ticket_system.get_ticket_fields()
        updated_milestone_field = self._get_ticket_field("milestone")

        self.assertNotEqual(fields, updated_fields)
        self.assertEqual(["milestone1", "milestone2", "milestone3", "milestone4"], milestone_field["options"])
        self.assertEqual(["milestone2", "milestone1", "milestone3", "milestone4"], updated_milestone_field["options"])
Example #15
0
    def _render_editor(self, req, milestone):
        # Suggest a default due time of 18:00 in the user's timezone
        now = datetime.now(req.tz)
        default_due = datetime(now.year, now.month, now.day, 18)
        if now.hour > 18:
            default_due += timedelta(days=1)
        default_due = to_datetime(default_due, req.tz)

        data = {
            "milestone": milestone,
            "datetime_hint": get_datetime_format_hint(req.lc_time),
            "default_due": default_due,
            "milestone_groups": [],
        }

        if milestone.exists:
            req.perm(milestone.resource).require("MILESTONE_MODIFY")
            milestones = [
                m
                for m in Milestone.select(self.env)
                if m.name != milestone.name and "MILESTONE_VIEW" in req.perm(m.resource)
            ]
            data["milestone_groups"] = group_milestones(milestones, "TICKET_ADMIN" in req.perm)
        else:
            req.perm(milestone.resource).require("MILESTONE_CREATE")

        chrome = Chrome(self.env)
        chrome.add_jquery_ui(req)
        chrome.add_wiki_toolbars(req)
        return "milestone_edit.html", data, None
Example #16
0
    def _render_editor(self, req, milestone):
        data = {
            "milestone": milestone,
            "datetime_hint": get_datetime_format_hint(req.lc_time),
            "default_due": self.get_default_due(req),
            "milestone_groups": [],
        }

        if milestone.exists:
            req.perm(milestone.resource).require("MILESTONE_MODIFY")
            milestones = [
                m
                for m in Milestone.select(self.env)
                if m.name != milestone.name and "MILESTONE_VIEW" in req.perm(m.resource)
            ]
            data["milestone_groups"] = group_milestones(milestones, "TICKET_ADMIN" in req.perm)
            data["num_open_tickets"] = milestone.get_num_tickets(exclude_closed=True)
            data["retarget_to"] = self.default_retarget_to
        else:
            req.perm(milestone.resource).require("MILESTONE_CREATE")
            if milestone.name:
                add_notice(req, _("Milestone %(name)s does not exist. You can" " create it here.", name=milestone.name))

        chrome = Chrome(self.env)
        chrome.add_jquery_ui(req)
        chrome.add_wiki_toolbars(req)
        add_stylesheet(req, "common/css/roadmap.css")
        return "milestone_edit.html", data, None
Example #17
0
    def test_update_milestone_update_tickets(self):
        self.env.db_transaction("INSERT INTO milestone (name) VALUES ('Test')")

        tkt1 = Ticket(self.env)
        tkt1.populate({"summary": "Foo", "milestone": "Test"})
        tkt1.insert()
        tkt2 = Ticket(self.env)
        tkt2.populate({"summary": "Bar", "milestone": "Test"})
        tkt2.insert()

        milestone = Milestone(self.env, "Test")
        milestone.name = "Testing"
        milestone.update()

        self.assertEqual("Testing", Ticket(self.env, tkt1.id)["milestone"])
        self.assertEqual("Testing", Ticket(self.env, tkt2.id)["milestone"])
Example #18
0
    def test_delete_milestone_retarget_tickets(self):
        cursor = self.db.cursor()
        cursor.execute("INSERT INTO milestone (name) VALUES ('Test')")
        cursor.close()

        tkt1 = Ticket(self.env)
        tkt1.populate({"summary": "Foo", "milestone": "Test"})
        tkt1.insert()
        tkt2 = Ticket(self.env)
        tkt2.populate({"summary": "Bar", "milestone": "Test"})
        tkt2.insert()

        milestone = Milestone(self.env, "Test")
        milestone.delete(retarget_to="Other")

        self.assertEqual("Other", Ticket(self.env, tkt1.id)["milestone"])
        self.assertEqual("Other", Ticket(self.env, tkt2.id)["milestone"])
Example #19
0
    def _reindex_milestone(self, realm, feedback, finish_fb):
        resources = Milestone.select(self.env)

        def check(milestone, check):
            return True

        index = self.milestone_created
        return self._index(realm, resources, check, index, feedback, finish_fb)
Example #20
0
    def test_select_milestones(self):
        self.env.db_transaction.executemany("INSERT INTO milestone (name) VALUES (%s)", [("1.0",), ("2.0",)])

        milestones = list(Milestone.select(self.env))
        self.assertEqual("1.0", milestones[0].name)
        assert milestones[0].exists
        self.assertEqual("2.0", milestones[1].name)
        assert milestones[1].exists
Example #21
0
    def test_create_and_update_milestone(self):
        milestone = Milestone(self.env)
        milestone.name = "Test"
        milestone.insert()

        self.assertEqual(
            [("Test", 0, 0, "")],
            self.env.db_query(
                """
            SELECT name, due, completed, description FROM milestone
            WHERE name='Test'
            """
            ),
        )

        # Use the same model object to update the milestone
        milestone.description = "Some text"
        milestone.update()
        self.assertEqual(
            [("Test", 0, 0, "Some text")],
            self.env.db_query(
                """
            SELECT name, due, completed, description FROM milestone
            WHERE name='Test'
            """
            ),
        )
Example #22
0
    def test_update_milestone_update_tickets(self):
        cursor = self.db.cursor()
        cursor.execute("INSERT INTO milestone (name) VALUES ('Test')")
        cursor.close()

        tkt1 = Ticket(self.env)
        tkt1.populate({"summary": "Foo", "milestone": "Test"})
        tkt1.insert()
        tkt2 = Ticket(self.env)
        tkt2.populate({"summary": "Bar", "milestone": "Test"})
        tkt2.insert()

        milestone = Milestone(self.env, "Test")
        milestone.name = "Testing"
        milestone.update()

        self.assertEqual("Testing", Ticket(self.env, tkt1.id)["milestone"])
        self.assertEqual("Testing", Ticket(self.env, tkt2.id)["milestone"])
Example #23
0
    def _render_confirm(self, req, db, milestone):
        req.perm(milestone.resource).require("MILESTONE_DELETE")

        milestones = [
            m
            for m in Milestone.select(self.env, db=db)
            if m.name != milestone.name and "MILESTONE_VIEW" in req.perm(m.resource)
        ]
        data = {"milestone": milestone, "milestone_groups": group_milestones(milestones, "TICKET_ADMIN" in req.perm)}
        return "milestone_delete.html", data, None
Example #24
0
    def test_select_milestones(self):
        cursor = self.db.cursor()
        cursor.executemany("INSERT INTO milestone (name) VALUES (%s)", [("1.0",), ("2.0",)])
        cursor.close()

        milestones = list(Milestone.select(self.env))
        self.assertEqual("1.0", milestones[0].name)
        assert milestones[0].exists
        self.assertEqual("2.0", milestones[1].name)
        assert milestones[1].exists
Example #25
0
 def list_view(self, req, cat, page):
     data = {
         "view": "list",
         "sprints": self.sm.select(),
         "format_datetime": datefmt.format_datetime,
         "date_hint": datefmt.get_date_format_hint(),
         "datetime_hint": datefmt.get_datetime_format_hint(),
         "milestones": [m.name for m in Milestone.select(self.env)],
     }
     data.update(req.args)
     return "agilo_admin_sprint.html", data
Example #26
0
 def default_retarget_to(self):
     if self._default_retarget_to and not any(
         self._default_retarget_to == m.name for m in Milestone.select(self.env)
     ):
         self.log.warn(
             'Milestone "%s" does not exist. Update the '
             '"default_retarget_to" option in the [milestone] '
             "section of trac.ini",
             self._default_retarget_to,
         )
     return self._default_retarget_to
    def _go_list(self, req):
        # search all artifacts.
        artifacts = ArtifactManager.find_all(self.env)

        milestones = [m for m in Milestone.select(self.env) if "MILESTONE_VIEW" in req.perm(m.resource)]

        # add artifacts to milestone.
        for m in milestones:
            artifacts_of_m = [artifact for artifact in artifacts if artifact.milestone == m.name]
            setattr(m, "artifacts", artifacts_of_m)

        data = {"milestones": milestones, "artifacts": artifacts}
        return "releaseartifactgraph.html", data, None
Example #28
0
    def _modify_resource_breadcrumb(self, req, template, data, content_type, is_active):
        """Provides logic for breadcrumb resource permissions
        """
        if data and ("ticket" in data.keys()) and data["ticket"].exists:
            data["resourcepath_template"] = "bh_path_ticket.html"
            # determine path permissions
            for resname, permname in [("milestone", "MILESTONE_VIEW"), ("product", "PRODUCT_VIEW")]:
                res = Resource(resname, data["ticket"][resname])
                data["path_show_" + resname] = permname in req.perm(res)

            # add milestone list + current milestone to the breadcrumb
            data["milestone_list"] = [m.name for m in Milestone.select(self.env)]
            mname = data["ticket"]["milestone"]
            if mname:
                data["milestone"] = Milestone(self.env, mname)
Example #29
0
    def users(self, req):
        """hours for all users"""

        data = {"hours_format": hours_format}

        ### date data
        self.date_data(req, data)

        ### milestone data
        milestone = req.args.get("milestone")
        milestones = Milestone.select(self.env)
        data["milestones"] = milestones

        ### get the hours
        # trachours = TracHoursPlugin(self.env)
        # tickets = trachours.tickets_with_hours()
        hours = get_all_dict(
            self.env,
            """
            SELECT * FROM ticket_time
            WHERE time_started >= %s AND time_started < %s
            """,
            *[int(time.mktime(i.timetuple())) for i in (data["from_date"], data["to_date"])]
        )
        worker_hours = {}
        for entry in hours:
            worker = entry["worker"]
            if worker not in worker_hours:
                worker_hours[worker] = 0

            if milestone and milestone != Ticket(self.env, entry["ticket"]).values.get("milestone"):
                continue

            worker_hours[worker] += entry["seconds_worked"]

        worker_hours = [(worker, seconds / 3600.0) for worker, seconds in sorted(worker_hours.items())]
        data["worker_hours"] = worker_hours

        if req.args.get("format") == "csv":
            req.send(self.export_csv(req, data))

        # add_link(req, 'prev', self.get_href(query, args, context.href),
        #         _('Prev Week'))
        # add_link(req, 'next', self.get_href(query, args, context.href),
        #         _('Next Week'))
        # prevnext_nav(req, _('Prev Week'), _('Next Week'))

        return "hours_users.html", data, "text/html"
Example #30
0
    def test_create_and_update_milestone(self):
        milestone = Milestone(self.env)
        milestone.name = "Test"
        milestone.insert()

        cursor = self.db.cursor()
        cursor.execute("SELECT name,due,completed,description FROM milestone " "WHERE name='Test'")
        self.assertEqual(("Test", 0, 0, ""), cursor.fetchone())

        # Use the same model object to update the milestone
        milestone.description = "Some text"
        milestone.update()
        cursor.execute("SELECT name,due,completed,description FROM milestone " "WHERE name='Test'")
        self.assertEqual(("Test", 0, 0, "Some text"), cursor.fetchone())