def _assert_doc_requirements(doc, is_update):
    """Assert experiment requirements."""
    tu.assert_iter(doc.requirements, 13, cim.v1.NumericalRequirement)

    # Initial condition.
    req = doc.requirements[0]
    tu.assert_object(req, cim.v1.InitialCondition)
    tu.assert_str(req.description, "Initial conditions are from", True)
    tu.assert_str(req.id, "ic.003")
    tu.assert_str(req.name, "3.3.ic")
    tu.assert_str(req.requirement_type, "initialCondition")

    # Boundary condition.
    req = doc.requirements[1]
    tu.assert_object(req, cim.v1.BoundaryCondition)
    tu.assert_str(req.requirement_type, "boundaryCondition")
    tu.assert_str(req.description, "Imposed changing concentrations", True)
    tu.assert_none(req.id)
    tu.assert_str(req.name, "3.3.bc.sls")

    # Boundary condition - options.
    tu.assert_iter(req.options, 2, cim.v1.NumericalRequirementOption)
    opt = req.options[0]
    tu.assert_str(opt.relationship, "XOR")
    tu.assert_object(opt.requirement, cim.v1.BoundaryCondition)
    # ... sub-requirement
    req = opt.requirement
    tu.assert_str(req.requirement_type, "boundaryCondition")
    tu.assert_str(req.description, "Concentrations")
    tu.assert_str(req.id, "bc.013")
    tu.assert_str(req.name, "3.3.bc.sls_conc")

    # Spatio Temporal Constraint.
    req = doc.requirements[12]
    tu.assert_object(req, cim.v1.SpatioTemporalConstraint)
    tu.assert_object(req.date_range, cim.v1.ClosedDateRange)
    tu.assert_str(req.date_range.duration, "P30Y")
    tu.assert_date(req.date_range.end, "2008-12-30 00:00:00+00:00")
    tu.assert_date(req.date_range.start, "1979-01-01 00:00:00+00:00")
    tu.assert_str(req.description, "Begin in 1979 and", True)
    tu.assert_str(req.id, "stc.027")
    tu.assert_str(req.name, "3.3.stc.1979_30yr")
    tu.assert_str(req.requirement_type, "spatioTemporalConstraint")
def _test(mod):
    """Performs a publishing workflow test."""
    # Create document.
    doc = _create_doc(mod)

    # Publish.
    pyesdoc.publish(doc)
    mod.DOC_VERSION += 1
    mod.assert_doc(doc)

    # Retrieve.
    doc = pyesdoc.retrieve(mod.DOC_ID, mod.DOC_VERSION)
    mod.assert_doc(doc)

    # Update.
    mod.update_doc(doc)
    mod.assert_doc_updates(doc)

    # Republish.
    pyesdoc.publish(doc)
    mod.DOC_VERSION += 1

    # Retrieve.
    doc = pyesdoc.retrieve(mod.DOC_ID, mod.DOC_VERSION)
    mod.assert_doc(doc, True)
    mod.assert_doc_updates(doc)

    # Republish.
    pyesdoc.publish(doc)
    mod.DOC_VERSION += 1

    # Unpublish.
    pyesdoc.unpublish(mod.DOC_ID, mod.DOC_VERSION)
    tu.assert_none(pyesdoc.retrieve(mod.DOC_ID, mod.DOC_VERSION))
    mod.DOC_VERSION -= 1

    # Retrieve specific.
    doc = pyesdoc.retrieve(mod.DOC_ID, mod.DOC_VERSION)
    mod.assert_doc(doc, True)
    mod.assert_doc_updates(doc)

    # Retrieve latest.
    doc = pyesdoc.retrieve(mod.DOC_ID, pyesdoc.ESDOC_DOC_VERSION_LATEST)
    mod.assert_doc(doc, True)
    mod.assert_doc_updates(doc)

    # Unpublish.
    pyesdoc.unpublish(mod.DOC_ID, mod.DOC_VERSION)
    tu.assert_none(pyesdoc.retrieve(mod.DOC_ID, mod.DOC_VERSION))
    mod.DOC_VERSION -= 1

    # Retrieve specific.
    doc = pyesdoc.retrieve(mod.DOC_ID, mod.DOC_VERSION)
    mod.assert_doc(doc)

    # Retrieve latest.
    doc = pyesdoc.retrieve(mod.DOC_ID, pyesdoc.ESDOC_DOC_VERSION_LATEST)
    mod.assert_doc(doc)

    # Unpublish (will delete document altogether).
    pyesdoc.unpublish(mod.DOC_ID, mod.DOC_VERSION)
    tu.assert_none(pyesdoc.retrieve(mod.DOC_ID, mod.DOC_VERSION))
    mod.DOC_VERSION -= 1
    tu.assert_none(pyesdoc.retrieve(mod.DOC_ID, mod.DOC_VERSION))