def test_get_publishing_dates_formats_time(self):
     with mock.patch('dmutils.dates.datetime') as mock_date:
         mock_date.utcnow.return_value = datetime.datetime(
             2015, 5, 22, 20, 39, 39, 417900)
         brief = {
             'requirementsLength': '1 week',
         }
         assert dates_package.datetime.utcnow() == datetime.datetime(
             2015, 5, 22, 20, 39, 39, 417900)
         assert dates_package.get_publishing_dates(
             brief)['closing_time'] == '11:59 pm'
    def test_get_publishing_dates_returns_correct_dates_if_published_at_key_is_a_date_object(
            self):
        brief = {
            'publishedAt': datetime.datetime(2016, 1, 4, 12, 0, 0),
        }

        dates = dates_package.get_publishing_dates(brief)

        assert dates['questions_close'] == datetime.datetime(
            2016, 1, 11, 23, 59, 59)
        assert dates['answers_close'] == datetime.datetime(
            2016, 1, 15, 23, 59, 59)
        assert dates['closing_date'] == datetime.datetime(
            2016, 1, 18, 23, 59, 59)
    def test_get_publishing_dates_returns_correct_dates_if_brief_is_published_with_no_requirementLength(
            self):
        brief = {
            'publishedAt': u'2016-01-04T12:00:00.00000Z',
        }

        dates = dates_package.get_publishing_dates(brief)

        assert dates['questions_close'] == datetime.datetime(
            2016, 1, 11, 23, 59, 59)
        assert dates['answers_close'] == datetime.datetime(
            2016, 1, 15, 23, 59, 59)
        assert dates['closing_date'] == datetime.datetime(
            2016, 1, 18, 23, 59, 59)
def preview_brief_source(framework_slug, lot_slug, brief_id):
    # This view's response currently is what will populate the iframes in the view above
    get_framework_and_lot(framework_slug,
                          lot_slug,
                          data_api_client,
                          allowed_statuses=['live'],
                          must_allow_brief=True)
    brief = data_api_client.get_brief(brief_id)["briefs"]

    if not is_brief_correct(brief, framework_slug, lot_slug,
                            current_user.id) or not brief_can_be_edited(brief):
        abort(404)

    # Check that all questions have been answered
    editable_content = content_loader.get_manifest(
        brief['frameworkSlug'], 'edit_brief').filter({'lot': brief['lotSlug']})
    unanswered_required, unanswered_optional = count_unanswered_questions(
        editable_content.summary(brief))
    if unanswered_required > 0:
        abort(400, 'There are still unanswered required questions')

    important_dates = get_publishing_dates(brief)

    display_content = content_loader.get_manifest(
        brief['frameworkSlug'], 'display_brief'
    ).filter({
        "lot": brief[
            "lotSlug"],  # 'lot' is deprecated so we can't rely on it being in brief object
        **brief,
    })

    # Get attributes in format suitable for govukSummaryList
    brief_summary = display_content.summary(brief)
    for section in brief_summary:
        section.summary_list = to_summary_list_rows(section.questions,
                                                    format_links=True,
                                                    filter_empty=False,
                                                    open_links_in_new_tab=True)

    # TODO: move preview_brief_source templates/includes into shared FE toolkit pattern to ensure it's kept in sync
    html = render_template("buyers/preview_brief_source.html",
                           content=display_content,
                           content_summary=brief_summary,
                           unanswered_required=unanswered_required,
                           brief=brief,
                           important_dates=important_dates)
    response_headers = {"X-Frame-Options": "sameorigin"}

    return html, 200, response_headers
    def test_get_publishing_dates_for_one_week_briefs_are_correct_if_published_on_a_thursday(
            self):
        with mock.patch('dmutils.dates.datetime') as mock_date:
            mock_date.utcnow.return_value = datetime.datetime(
                2016, 7, 7, 15, 21, 39, 417900)
            brief = {
                'requirementsLength': '1 week',
            }

            dates = dates_package.get_publishing_dates(brief)

            assert dates['questions_close'] == datetime.datetime(
                2016, 7, 11, 23, 59, 59)
            assert dates['answers_close'] == datetime.datetime(
                2016, 7, 13, 23, 59, 59)
            assert dates['closing_date'] == datetime.datetime(
                2016, 7, 14, 23, 59, 59)
def view_brief_timeline(framework_slug, lot_slug, brief_id):
    get_framework_and_lot(framework_slug,
                          lot_slug,
                          data_api_client,
                          allowed_statuses=['live', 'expired'],
                          must_allow_brief=True)
    brief = data_api_client.get_brief(brief_id)["briefs"]
    if not is_brief_correct(brief, framework_slug, lot_slug,
                            current_user.id) or brief.get('status') != 'live':
        abort(404)

    dates = get_publishing_dates(brief)

    return render_template("buyers/brief_publish_confirmation.html",
                           email_address=brief['users'][0]['emailAddress'],
                           published=True,
                           brief=brief,
                           dates=dates), 200
def publish_brief(framework_slug, lot_slug, brief_id):
    get_framework_and_lot(framework_slug,
                          lot_slug,
                          data_api_client,
                          allowed_statuses=['live'],
                          must_allow_brief=True)
    brief = data_api_client.get_brief(brief_id)["briefs"]

    if not is_brief_correct(brief, framework_slug, lot_slug,
                            current_user.id) or not brief_can_be_edited(brief):
        abort(404)

    content = content_loader.get_manifest(
        brief['frameworkSlug'], 'edit_brief').filter({'lot': brief['lotSlug']})
    brief_users = brief['users'][0]
    brief_user_name = brief_users['name']

    sections = content.summary(brief)
    question_and_answers = {}
    question_and_answers_content = sections.get_question(
        'questionAndAnswerSessionDetails')
    question_and_answers['id'] = question_and_answers_content['id']

    # Annotate the section data with the section slug/id, to construct the Edit link in the template
    for section in sections:
        if section.get_question('questionAndAnswerSessionDetails'
                                ) == question_and_answers_content:
            question_and_answers['slug'] = section['id']

    unanswered_required, unanswered_optional = count_unanswered_questions(
        sections)

    if request.method == 'POST':
        if unanswered_required > 0:
            abort(400, 'There are still unanswered required questions')
        data_api_client.publish_brief(brief_id, brief_user_name)
        return redirect(
            # the 'published' parameter is for tracking this request by analytics
            url_for('.view_brief_overview',
                    framework_slug=brief['frameworkSlug'],
                    lot_slug=brief['lotSlug'],
                    brief_id=brief['id'],
                    published='true'))
    else:
        #  requirements length is a required question but is handled separately to other
        #  required questions on the publish page if it's unanswered.
        if (sections.get_section(
                'set-how-long-your-requirements-will-be-open-for')
                and sections.get_section(
                    'set-how-long-your-requirements-will-be-open-for').
                questions[0].answer_required):
            unanswered_required -= 1

        email_address = brief_users['emailAddress']
        dates = get_publishing_dates(brief)

        return render_template("buyers/brief_publish_confirmation.html",
                               email_address=email_address,
                               question_and_answers=question_and_answers,
                               unanswered_required=unanswered_required,
                               sections=sections,
                               brief=brief,
                               dates=dates), 200