def test_fail_classification_id(app):
    request_plan_data = deepcopy(test_plan_data)
    request_plan_data["classification"] = {
        "scheme": u"ДК021",
        "description": "Personal care products",
        "id": "33700000-7",
    }
    del request_plan_data["items"]

    app.authorization = ("Basic", ("broker", "broker"))
    response = app.post_json("/plans", {"data": request_plan_data})
    plan = response.json

    request_tender_data = deepcopy(test_below_tender_data)
    request_tender_data["items"][0]["classification"] = {
        "scheme": u"ДК021",
        "description": "Antiperspirants",
        "id": "33711120-4",
    }
    response = app.post_json("/plans/{}/tenders".format(plan["data"]["id"]), {"data": request_tender_data}, status=422)
    error_data = response.json["errors"]
    assert len(error_data) > 0
    error = error_data[0]
    assert error["name"] == "items[0].classification.id"
    assert (
        error["description"] == "Plan classification.id 33700000-7 and item's 33711120-4 "
        "should be of the same group 3370"
    )
def test_fail_classification_id_336(app):
    request_plan_data = deepcopy(test_plan_data)
    request_plan_data["classification"] = {
        "scheme": "ДК021",
        "description": "Pharmaceutical products",
        "id": "33600000-6",
    }
    del request_plan_data["items"]

    app.authorization = ("Basic", ("broker", "broker"))
    response = app.post_json("/plans", {"data": request_plan_data})
    plan = response.json

    request_tender_data = deepcopy(test_below_tender_data)
    request_tender_data["items"] = request_tender_data["items"][:1]
    request_tender_data["items"][0]["classification"] = {
        "scheme": "ДК021",
        "description": "Makeup kits",
        "id": "33711420-7",
    }
    response = app.post_json("/plans/{}/tenders".format(plan["data"]["id"]),
                             {"data": request_tender_data},
                             status=422)
    error_data = response.json["errors"]
    assert len(error_data) > 0
    error = error_data[0]
    assert error["name"] == "items[0].classification.id"
    assert (error["description"] ==
            "Plan classification.id 33600000-6 and item's 33711420-7 "
            "should be of the same group 336")
Example #3
0
def test_fail_complete_manually(app, value):
    app.authorization = ("Basic", ("broker", "broker"))
    test_data = deepcopy(test_plan_data)
    test_data["status"] = "scheduled"
    test_data["tender"]["procurementMethodType"] = value
    if value == "aboveThresholdUA.defense":
        patch_date = get_now() + timedelta(days=1)
    else:
        patch_date = get_now() - timedelta(days=1)

    if value in ("aboveThresholdUA.defense", "simple.defense"):

        with patch(
                "openprocurement.planning.api.validation.RELEASE_SIMPLE_DEFENSE_FROM",
                patch_date):
            response = app.post_json("/plans", {"data": test_data}, status=403)
        assert response.status == "403 Forbidden"
        assert response.json["errors"] == [{
            u'description':
            u'procuringEntity with general kind cannot publish this type of procedure.'
            u' Procurement method types allowed for this kind: centralizedProcurement, reporting,'
            u' negotiation, negotiation.quick, priceQuotation, belowThreshold, aboveThresholdUA, aboveThresholdEU,'
            u' competitiveDialogueUA, competitiveDialogueEU, esco, closeFrameworkAgreementUA.',
            u'location':
            u'body',
            u'name':
            u'kind'
        }]
        test_data["procuringEntity"]["kind"] = "defense"

    with patch(
            "openprocurement.planning.api.validation.RELEASE_SIMPLE_DEFENSE_FROM",
            patch_date):
        response = app.post_json("/plans", {"data": test_data})
    assert response.status == "201 Created"
    assert response.json["data"]["status"] == "scheduled"
    plan_id = response.json["data"]["id"]
    acc_token = response.json["access"]["token"]

    response = app.patch_json("/plans/{}?acc_token={}".format(
        plan_id, acc_token), {"data": {
            "status": "complete"
        }},
                              status=422)
    assert response.json == {
        "status":
        "error",
        "errors": [{
            "location":
            "body",
            "name":
            "status",
            "description": [
                "Can't complete plan with '{}' tender.procurementMethodType".
                format(value)
            ],
        }],
    }
def test_post_milestone_author_validate_identifier(app, centralized_plan):
    """
    milestone can only be posted if author equals plan.procuringEntity
    """
    plan, access_token = centralized_plan

    app.authorization = ("Basic", ("broker", "broker"))
    data = test_milestone_data(app)
    data["author"]["name"] = "ЦЗО 2"
    app.post_json("/plans/{}/milestones".format(plan["id"]), {"data": data},
                  status=201)
def test_procurement_method_type_cpb(app):
    app.authorization = ("Basic", ("broker", "broker"))

    request_plan_data = deepcopy(test_plan_data)
    request_plan_data["tender"]["procurementMethod"] = ""
    request_plan_data["tender"]["procurementMethodType"] = "centralizedProcurement"

    response = app.post_json("/plans", {"data": request_plan_data})
    plan = response.json

    response = app.post_json("/plans/{}/tenders".format(plan["data"]["id"]), {"data": test_below_tender_data})
    assert response.status == "201 Created"
def test_fail_procurement_method_type_validation(app):
    app.authorization = ("Basic", ("broker", "broker"))

    request_plan_data = deepcopy(test_plan_data)
    request_plan_data["tender"]["procurementMethodType"] = "aboveThresholdUA"
    response = app.post_json("/plans", {"data": request_plan_data})
    plan = response.json

    response = app.post_json(
        "/plans/{}/tenders".format(plan["data"]["id"]), {"data": test_below_tender_data}, status=422
    )
    errors = response.json["errors"]
    assert len(errors) == 1
    assert errors[0]["name"] == "procurementMethodType"
    assert errors[0]["description"] == "procurementMethodType doesn't match: aboveThresholdUA != belowThreshold"
Example #7
0
def test_plan_default_status(app):
    app.authorization = ("Basic", ("broker", "broker"))
    test_data = deepcopy(test_plan_data)

    test_data.pop("status", None)
    response = app.post_json("/plans", {"data": test_data})
    assert response.json["data"].get("status") == "scheduled"

    test_data["status"] = None
    response = app.post_json("/plans", {"data": test_data})
    assert response.json["data"].get("status") == "scheduled"

    response = app.get("/plans")
    assert response.status == "200 OK"
    assert len(response.json["data"]) == 2
def test_fail_post_another_milestone(app, centralized_milestone, test_status):
    """
    broker can't post another milestone with the same author
    till the first milestone in scheduled or met statuses
    """
    milestone_data, plan_data = centralized_milestone[
        "milestone"], centralized_milestone["plan"]
    milestone, milestone_token = milestone_data["data"], milestone_data[
        "token"]
    plan, plan_token = plan_data["data"], plan_data["token"]

    # set milestone status
    if test_status != milestone["status"]:
        plan_source = app.app.registry.db.get(plan["id"])
        plan_source["milestones"][0]["status"] = test_status
        app.app.registry.db.save(plan_source)

    response = app.post_json("/plans/{}/milestones".format(plan["id"]),
                             {"data": test_milestone_data(app)},
                             status=422)
    assert response.json == {
        u'status':
        u'error',
        u'errors': [{
            u'description':
            u'An active milestone already exists for this author',
            u'location': u'data',
            u'name': u'author'
        }]
    }
Example #9
0
def test_fail_update_back_to_draft(app, initial_status):
    app.authorization = ("Basic", ("broker", "broker"))
    test_data = deepcopy(test_plan_data)

    test_data["status"] = initial_status
    response = app.post_json("/plans", {"data": test_data})
    assert response.json["data"].get("status") == "scheduled"
    plan_id = response.json["data"]["id"]
    acc_token = response.json["access"]["token"]

    if initial_status is None:
        plan = app.app.registry.db.get(plan_id)
        del plan["status"]
        app.app.registry.db.save(plan)

    response = app.patch_json("/plans/{}?acc_token={}".format(
        plan_id, acc_token), {"data": {
            "status": "draft"
        }},
                              status=422)
    assert response.json == {
        u"status":
        u"error",
        u"errors": [{
            u"description": u"Plan status can not be changed back to 'draft'",
            u"location": u"body",
            u"name": u"status",
        }],
    }
Example #10
0
def test_cancel_compatibility_completed_plan(app):
    """
    well I don't know if it's an appropriate case. it's probably not
    """
    app.authorization = ("Basic", ("broker", "broker"))
    test_data = deepcopy(test_plan_data)
    response = app.post_json("/plans", {"data": test_data})
    assert response.status == "201 Created"

    plan = response.json["data"]
    acc_token = response.json["access"]["token"]

    obj = app.app.registry.db.get(plan["id"])
    del obj["status"]
    obj["tender_id"] = "a" * 32
    app.app.registry.db.save(obj)

    response = app.get("/plans/{}".format(plan["id"]))
    assert response.json["data"]["status"] == "complete"  # complete !

    response = app.patch_json(
        "/plans/{}?acc_token={}".format(plan["id"], acc_token), {
            "data": {
                "cancellation": {
                    "reason": "Because it's possible",
                    "status": "active"
                }
            }
        })
    assert response.status == "200 OK"
    assert response.json["data"]["status"] == "cancelled"  # cancelled !
Example #11
0
def test_plan_update_draft(app, mode, status):
    app.authorization = ("Basic", ("broker", "broker"))
    test_data = deepcopy(test_plan_data)
    if mode != "real":
        test_data["mode"] = "test"
    test_data["status"] = "draft"
    response = app.post_json("/plans", {"data": test_data})
    assert response.status == "201 Created"
    assert response.json["data"].get("status") == "draft"
    plan_id = response.json["data"]["id"]
    acc_token = response.json["access"]["token"]

    response = app.patch_json(
        "/plans/{}?acc_token={}".format(plan_id, acc_token),
        {"data": {
            "status": status
        }})
    assert response.status == "200 OK"
    assert response.json["data"].get("status") == status

    response = app.get("/plans?mode={}".format(mode))
    assert response.status == "200 OK"
    assert len(response.json["data"]) == 1
    assert response.json["data"][0]["id"] == plan_id

    response = app.get("/plans?feed=changes&mode={}".format(mode))
    assert response.status == "200 OK"
    assert len(response.json["data"]) == 1
    assert response.json["data"][0]["id"] == plan_id
def test_update_status_invalid(app):
    app.authorization = ("Basic", ("broker", "broker"))
    test_data = deepcopy(test_plan_data)

    test_data["status"] = "draft"
    response = app.post_json("/plans", {"data": test_data})
    assert response.json["data"].get("status") == "draft"
    plan_id = response.json["data"]["id"]
    acc_token = response.json["access"]["token"]

    response = app.patch_json(
        "/plans/{}?acc_token={}".format(plan_id, acc_token), {"data": {"status": "invalid"}}, status=422
    )
    assert response.json == {
        "status": "error",
        "errors": [
            {
                "location": "body",
                "name": "status",
                "description": ["Value must be one of ['draft', 'scheduled', 'cancelled', 'complete']."],
            }
        ],
    }

    response = app.patch_json(
        "/plans/{}?acc_token={}".format(plan_id, acc_token), {"data": {"status": "cancelled"}}, status=422
    )
    assert response.json == {
        "status": "error",
        "errors": [
            {"description": ["An active cancellation object is required"], "location": "body", "name": "status"}
        ],
    }
def test_cancel_plan_1_step(app):
    app.authorization = ("Basic", ("broker", "broker"))
    test_data = deepcopy(test_plan_data)
    test_data["status"] = "scheduled"
    response = app.post_json("/plans", {"data": test_data})
    assert response.status == "201 Created"
    assert response.json["data"].get("status") == "scheduled"
    plan_id = response.json["data"]["id"]
    acc_token = response.json["access"]["token"]

    response = app.patch_json(
        "/plans/{}?acc_token={}".format(plan_id, acc_token),
        {"data": {"cancellation": {"reason": "", "status": "active"}}},
        status=422,
    )
    assert response.json == {
        "status": "error",
        "errors": [
            {"location": "body", "name": "cancellation", "description": {"reason": ["String value is too short."]}}
        ],
    }

    response = app.patch_json(
        "/plans/{}?acc_token={}".format(plan_id, acc_token),
        {"data": {"cancellation": {"reason": "Because", "status": "active"}}},
    )
    assert response.status == "200 OK"
    assert response.json["data"]["cancellation"]["status"] == "active"
    assert response.json["data"]["status"] == "cancelled"

    plan = app.app.registry.databases.plans.get(plan_id)
    assert {c["path"] for c in plan["revisions"][-1]["changes"]} == {"/cancellation", "/status"}
def test_cancel_plan_2_steps(app, initial_status):
    app.authorization = ("Basic", ("broker", "broker"))
    test_data = deepcopy(test_plan_data)
    test_data["status"] = initial_status
    response = app.post_json("/plans", {"data": test_data})
    assert response.status == "201 Created"
    assert response.json["data"].get("status") == initial_status
    plan_id = response.json["data"]["id"]
    acc_token = response.json["access"]["token"]

    response = app.patch_json(
        "/plans/{}?acc_token={}".format(plan_id, acc_token),
        {"data": {"cancellation": {"reason": "Because", "status": "pending"}}},
    )
    assert response.status == "200 OK"
    assert response.json["data"]["cancellation"]["status"] == "pending"
    assert response.json["data"].get("status") == initial_status
    create_time = response.json["data"]["cancellation"]["date"]

    response = app.patch_json(
        "/plans/{}?acc_token={}".format(plan_id, acc_token), {"data": {"cancellation": {"status": "active"}}}
    )
    assert response.status == "200 OK"
    assert response.json["data"]["cancellation"]["status"] == "active"
    assert response.json["data"]["cancellation"]["date"] > create_time
    assert response.json["data"]["status"] == "cancelled"

    get_response = app.get("/plans/{}".format(plan_id))
    assert get_response.json["data"]["cancellation"]["date"] == response.json["data"]["cancellation"]["date"]
def test_fail_post_milestone_author(app, centralized_plan):
    """
    milestone can only be posted if author equals plan.procuringEntity
    """
    plan, access_token = centralized_plan

    app.authorization = ("Basic", ("broker", "broker"))
    data = test_milestone_data(app)
    data["author"] = {
        "identifier": {
            "scheme": "UA-EDR",
            "id": "222222",
            "legalName": "ЦЗО 2"
        },
        "name": "ЦЗО 2"
    }
    response = app.post_json("/plans/{}/milestones".format(plan["id"]),
                             {"data": data},
                             status=422)
    assert response.json == {
        u"status":
        u"error",
        u"errors": [{
            u"description": u"Should match plan.procuringEntity",
            u"location": u"data",
            u"name": u"author"
        }]
    }
Example #16
0
def test_fail_complete_manually(app, value):
    app.authorization = ("Basic", ("broker", "broker"))
    test_data = deepcopy(test_plan_data)
    test_data["status"] = "scheduled"
    test_data["tender"]["procurementMethodType"] = value
    response = app.post_json("/plans", {"data": test_data})
    assert response.status == "201 Created"
    assert response.json["data"]["status"] == "scheduled"
    plan_id = response.json["data"]["id"]
    acc_token = response.json["access"]["token"]

    response = app.patch_json("/plans/{}?acc_token={}".format(
        plan_id, acc_token), {"data": {
            "status": "complete"
        }},
                              status=422)
    assert response.json == {
        "status":
        "error",
        "errors": [{
            "location":
            "body",
            "name":
            "status",
            "description": [
                "Can't complete plan with '{}' tender.procurementMethodType".
                format(value)
            ],
        }],
    }
def test_fail_tender_creation(app):
    app.authorization = ("Basic", ("broker", "broker"))
    request_tender_data = deepcopy(test_below_tender_data)
    request_plan_data = deepcopy(test_plan_data)
    plan = create_plan_for_tender(app, request_tender_data, request_plan_data)

    # rm milestones that causes data error
    request_tender_data["enquiryPeriod"][
        "endDate"] = "2019-01-02T00:00:00+02:00"

    response = app.post_json("/plans/{}/tenders".format(plan["data"]["id"]),
                             {"data": request_tender_data},
                             status=422)
    assert response.json == {
        "status":
        "error",
        "errors": [{
            "description": {
                "startDate": ["period should begin before its end"]
            },
            "location": "body",
            "name": "enquiryPeriod",
        }],
    }

    # get plan form db
    plan_from_db = app.app.registry.databases.plans.get(plan["data"]["id"])
    assert plan_from_db.get("tender_id") is None
def centralized_plan(app):
    app.authorization = ("Basic", ("broker", "broker"))
    test_data = deepcopy(test_plan_data)
    test_data["tender"]["procurementMethod"] = ""
    test_data["tender"]["procurementMethodType"] = "centralizedProcurement"
    test_data["procuringEntity"] = central_procuring_entity
    response = app.post_json("/plans", {"data": test_data})
    return response.json["data"], response.json["access"]["token"]
def test_create_cancelled(app, replaced_status):
    app.authorization = ("Basic", ("broker", "broker"))
    test_data = deepcopy(test_plan_data)
    test_data["status"] = replaced_status  # this will be replaced by "switch_status" serializable
    test_data["cancellation"] = {"reason": "Because it's possible", "status": "active"}
    response = app.post_json("/plans", {"data": test_data})
    assert response.status == "201 Created"
    assert response.json["data"].get("status") == "cancelled"
Example #20
0
def test_fail_cd_second_stage_creation(app, plan, request_tender_data):
    app.authorization = ("Basic", ("broker", "broker"))
    response = app.post_json("/plans/{}/tenders".format(plan["data"]["id"]), {"data": request_tender_data}, status=403)
    error_data = response.json["errors"]
    assert len(error_data) > 0
    error = error_data[0]
    assert error["name"] == "accreditation"
    assert u"Broker Accreditation level does not permit tender creation" == error["description"]
Example #21
0
def test_success_classification_id(app):
    request_plan_data = deepcopy(test_plan_data)
    request_plan_data["classification"] = {"scheme": u"ДК021", "description": "Antiperspirants", "id": "33711120-4"}
    del request_plan_data["items"]

    app.authorization = ("Basic", ("broker", "broker"))
    response = app.post_json("/plans", {"data": request_plan_data})
    plan = response.json

    request_tender_data = deepcopy(test_below_tender_data)
    request_tender_data["items"][0]["classification"] = {
        "scheme": u"ДК021",
        "description": "Make-up preparations",
        "id": "33711200-9",
    }
    response = app.post_json("/plans/{}/tenders".format(plan["data"]["id"]), {"data": request_tender_data})
    assert response.status == "201 Created"
Example #22
0
def test_plan_tenders_404(app):
    app.authorization = ("Basic", ("broker", "broker"))
    response = app.post_json("/plans/{}/tenders".format("a" * 32), {"data": {}}, status=404)
    assert response.status == "404 Not Found"
    assert response.content_type == "application/json"
    assert response.json == {
        u"status": u"error",
        u"errors": [{u"description": u"Not Found", u"location": u"url", u"name": u"plan_id"}],
    }
Example #23
0
def test_success_classification_id_336(app):
    request_plan_data = deepcopy(test_plan_data)
    request_plan_data["classification"] = {"scheme": u"ДК021", "description": "Insulin", "id": "33615100-5"}
    del request_plan_data["items"]

    app.authorization = ("Basic", ("broker", "broker"))
    response = app.post_json("/plans", {"data": request_plan_data})
    plan = response.json

    request_tender_data = deepcopy(test_below_tender_data)
    request_tender_data["items"] = request_tender_data["items"][:1]
    request_tender_data["items"][0]["classification"] = {
        "scheme": u"ДК021",
        "description": "Medicinal products for dermatology",
        "id": "33631000-2",
    }
    response = app.post_json("/plans/{}/tenders".format(plan["data"]["id"]), {"data": request_tender_data})
    assert response.status == "201 Created"
def centralized_milestone(app, centralized_plan):
    plan, access_token = centralized_plan
    response = app.post_json("/plans/{}/milestones".format(plan["id"]),
                             {"data": test_milestone_data(app)})
    assert response.status_code == 201
    result = dict(milestone=dict(data=response.json["data"],
                                 token=response.json["access"]["token"]),
                  plan=dict(data=plan, token=access_token))
    return result
def test_forbidden_update_milestone_documents(app, centralized_milestone):
    """
    Plan owner or just broker can't manage milestone documents
    """
    milestone_data, plan_data = centralized_milestone[
        "milestone"], centralized_milestone["plan"]
    milestone, milestone_token = milestone_data["data"], milestone_data[
        "token"]
    plan, plan_token = plan_data["data"], plan_data["token"]
    app.authorization = ("Basic", ("broker", "broker"))

    response = app.post_json(
        "/plans/{}/milestones/{}/documents?acc_token={}".format(
            plan["id"], milestone["id"], plan_token), {"data": {}},
        status=403)
    assert response.json == {
        u"status":
        u"error",
        u"errors": [{
            u"description": u"Forbidden",
            u"location": u"url",
            u"name": u"permission"
        }]
    }

    # put
    document = milestone["documents"][0]
    response = app.put_json(
        "/plans/{}/milestones/{}/documents/{}?acc_token={}".format(
            plan["id"], milestone["id"], document["id"],
            plan_token), {"data": {}},
        status=403)
    assert response.json == {
        u"status":
        u"error",
        u"errors": [{
            u"description": u"Forbidden",
            u"location": u"url",
            u"name": u"permission"
        }]
    }

    # patch
    response = app.patch_json(
        "/plans/{}/milestones/{}/documents/{}?acc_token={}".format(
            plan["id"], milestone["id"], document["id"],
            plan_token), {"data": {}},
        status=403)
    assert response.json == {
        u"status":
        u"error",
        u"errors": [{
            u"description": u"Forbidden",
            u"location": u"url",
            u"name": u"permission"
        }]
    }
def test_success_plan_tenders_creation(app, request_tender_data):
    app.authorization = ("Basic", ("broker", "broker"))
    request_plan_data = deepcopy(test_plan_data)

    if request_tender_data["procurementMethodType"] in (
            "aboveThresholdUA.defense", "simple.defense"):
        request_plan_data['procuringEntity']['kind'] = 'defense'
    plan = create_plan_for_tender(app, request_tender_data, request_plan_data)

    response = app.post_json("/plans/{}/tenders".format(plan["data"]["id"]),
                             {"data": request_tender_data})
    assert response.status == "201 Created"

    tender_data = response.json["data"]
    assert tender_data["plans"] == [{"id": plan["data"]["id"]}]
    assert tender_data["title"] == request_tender_data["title"]
    assert response.headers[
        "Location"] == "http://localhost/api/2.5/tenders/{}".format(
            tender_data["id"])

    # get plan
    response = app.get("/plans/{}".format(plan["data"]["id"]))
    assert response.json["data"]["tender_id"] == tender_data["id"]

    # removing status (if the tender was created before the plan statuses release)
    plan_from_db = app.app.registry.databases.plans.get(plan["data"]["id"])
    del plan_from_db["status"]
    app.app.registry.databases.plans.save(plan_from_db)

    # add another tender
    response = app.post_json("/plans/{}/tenders".format(plan["data"]["id"]),
                             {"data": request_tender_data},
                             status=422)
    error_data = response.json["errors"]
    assert len(error_data) == 1
    error = error_data[0]
    assert error["location"] == "body"
    assert error["name"] == "tender_id"
    assert error["description"] == "This plan has already got a tender"

    # check plan status
    get_response = app.get("/plans/{}".format(plan["data"]["id"]))
    assert get_response.json["data"]["status"] == "complete"
Example #27
0
def test_fail_cfa_second_stage_creation(app, plan):
    app.authorization = ("Basic", ("broker", "broker"))
    response = app.post_json(
        "/plans/{}/tenders".format(plan["data"]["id"]), {"data": cfa_selection_tender_data}, status=422
    )
    error_data = response.json["errors"]
    assert len(error_data) > 0
    error = error_data[0]
    assert error["name"] == "procurementMethodType"
    assert error["description"].startswith(u"Should be one of the first stage values:")
Example #28
0
def test_fail_identifier_scheme_validation(app):
    app.authorization = ("Basic", ("broker", "broker"))

    request_plan_data = deepcopy(test_plan_data)
    request_plan_data["procuringEntity"]["identifier"]["scheme"] = "AE-DCCI"
    response = app.post_json("/plans", {"data": request_plan_data})
    plan = response.json

    response = app.post_json(
        "/plans/{}/tenders?acc_token={}".format(plan["data"]["id"], plan["access"]["token"]),
        {"data": test_below_tender_data},
        status=422,
    )
    errors = response.json["errors"]
    assert len(errors) == 1
    assert errors[0]["name"] == "procuringEntity"
    plan_identifier = plan["data"]["procuringEntity"]["identifier"]
    tender_identifier = test_below_tender_data["procuringEntity"]["identifier"]
    assert errors[0]["description"] == "procuringEntity.identifier doesn't match: {} {} != {} {}".format(
        plan_identifier["scheme"], plan_identifier["id"], tender_identifier["scheme"], tender_identifier["id"]
    )
def test_fail_create_plan_with_milestone(app):
    app.authorization = ("Basic", ("broker", "broker"))
    test_data = deepcopy(test_plan_data)
    test_data["status"] = "draft"
    test_data["milestones"] = [{
        "title": MILESTONE_APPROVAL_TITLE,
        "type": Milestone.TYPE_APPROVAL,
        "author": milestone_author,
        "dueDate": "2001-10-30T11:15:26.641038+03:00"
    }]
    response = app.post_json("/plans", {"data": test_data})
    assert "milestones" not in response.json["data"]
def test_fail_pass_plans(app, plan, request_tender_data):
    """
    "plans" field cannot be set via 'data'
    """
    app.authorization = ("Basic", ("broker", "broker"))
    tender_data = dict(**request_tender_data)
    tender_data["plans"] = [{"id": plan["data"]["id"]}]
    response = app.post_json("/tenders", {"data": request_tender_data})
    assert response.status == "201 Created"
    tender_data = response.json["data"]

    assert "plans" not in tender_data  # NOT in
    assert tender_data["title"] == request_tender_data["title"]