Package gaej2011.controller

Source Code of gaej2011.controller.MinutesControllerTest$MailDelegate

package gaej2011.controller;

import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import static org.junit.matchers.JUnitMatchers.*;
import gaej2011.meta.MinutesMeta;
import gaej2011.model.Minutes;
import gaej2011.service.MemoService;
import gaej2011.service.MinutesService;

import java.io.IOException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Future;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletResponse;

import org.junit.Test;
import org.slim3.datastore.Datastore;
import org.slim3.tester.ControllerTestCase;
import org.slim3.tester.TestEnvironment;

import com.google.appengine.api.blobstore.BlobKey;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.mail.MailServicePb.MailMessage;
import com.google.apphosting.api.ApiProxy;
import com.google.apphosting.api.ApiProxy.ApiConfig;
import com.google.apphosting.api.ApiProxy.ApiProxyException;
import com.google.apphosting.api.ApiProxy.Delegate;
import com.google.apphosting.api.ApiProxy.Environment;
import com.google.apphosting.api.ApiProxy.LogRecord;

public class MinutesControllerTest extends ControllerTestCase {

    static final String PATH = "/Minutes";

    @Test
    public void 議事録のタイトルを作成できる() throws NullPointerException,
            IllegalArgumentException, IOException, ServletException {
        // test@example.com というユーザがログイン中、という状態を作っておく。
        TestEnvironment environment =
            (TestEnvironment) ApiProxy.getCurrentEnvironment();
        environment.setEmail("test@example.com");

        tester.request.setMethod("POST");
        tester.param("title", " テスト用議事録1");
        tester.start(PATH);
        assertThat(
            "MinutesController のインスタンスが使用される",
            tester.getController(),
            instanceOf(MinutesController.class));
        assertThat(
            " レスポンスコードが204",
            tester.response.getStatus(),
            is(HttpServletResponse.SC_NO_CONTENT));
    }

    @Test
    public void 議事録のタイトルを作成できる_パラメータを指定しない() throws NullPointerException,
            IllegalArgumentException, IOException, ServletException {
        // test@example.com というユーザがログイン中、という状態を作っておく。
        TestEnvironment environment =
            (TestEnvironment) ApiProxy.getCurrentEnvironment();
        environment.setEmail("test@example.com");

        tester.request.setMethod("POST");
        tester.start(PATH);
        assertThat(
            "MinutesController のインスタンスが使用される",
            tester.getController(),
            instanceOf(MinutesController.class));
        assertThat(
            " レスポンスコードが400",
            tester.response.getStatus(),
            is(HttpServletResponse.SC_BAD_REQUEST));
    }

    @Test
    public void 議事録のタイトルを作成できる_ログインしていない() throws NullPointerException,
            IllegalArgumentException, IOException, ServletException {
        tester.request.setMethod("POST");
        tester.start(PATH);
        assertThat(
            " レスポンスコードが401",
            tester.response.getStatus(),
            is(HttpServletResponse.SC_UNAUTHORIZED));
    }

    @Test
    public void 議事録の一覧を新しい順に表示できる() throws NullPointerException,
            IllegalArgumentException, IOException, ServletException {
        for (int i = 0; i < 5; i++) {
            Minutes minutes = new Minutes();
            minutes.setTitle(" テスト用議事録" + i);
            minutes.setCreatedAt(new Date());
            Datastore.put(minutes);
        }
        tester.request.setMethod("GET");
        tester.start(PATH);
        assertThat(
            "MinutesController のインスタンスが使用される",
            tester.getController(),
            instanceOf(MinutesController.class));
        assertThat(
            " レスポンスコードが200",
            tester.response.getStatus(),
            is(HttpServletResponse.SC_OK));
        assertThat(
            "Content-Type はapplication/json",
            tester.response.getContentType(),
            is("application/json"));
        assertThat(
            "Chancter-Encoding はutf-8",
            tester.response.getCharacterEncoding(),
            is("utf-8"));
        String json = tester.response.getOutputAsString();
        System.out.println(json);
        Minutes[] minutes = MinutesMeta.get().jsonToModels(json);
        assertThat(" 全ての議事録が返る", minutes.length, is(5));
    }

    @Test
    public void 議事録のTSVをダウンロードする() throws IOException, NullPointerException,
            IllegalArgumentException, ServletException {
        // test@example.com というユーザがログイン中、という状態を作っておく。
        TestEnvironment environment =
            (TestEnvironment) ApiProxy.getCurrentEnvironment();
        environment.setEmail("test@example.com");
        Key minutesKey = MinutesService.put(" テスト用議事録");
        for (int i = 0; i < 5; i++) {
            MemoService.put(minutesKey, "memo" + i);
        }
        Minutes minutes = Datastore.get(Minutes.class, minutesKey);
        BlobKey blobKey = MinutesService.exportAsTSV(minutes);
        tester.param("download", blobKey.getKeyString());
        tester.start(PATH);
        assertThat(
            "MinutesController のインスタンスが使用される",
            tester.getController(),
            instanceOf(MinutesController.class));
        assertThat(
            " レスポンスコードが200",
            tester.response.getStatus(),
            is(HttpServletResponse.SC_OK));
        assertThat(
            "Content-Type はTSV",
            tester.response.getContentType(),
            is("text/tab-separated-values"));
        assertThat(
            "Content-Length が指定されている",
            tester.response.getContentLength(),
            is(not(0)));
        assertThat(
            "Content-disposition ヘッダにファイル名が指定されている",
            tester.response.getHeader("Content-disposition"),
            is("attachment; テスト用議事録"));
        assertThat(
            " コンテントのサイズ=Content-Length",
            tester.response.getOutputAsByteArray().length,
            is(tester.response.getContentLength()));
    }

    @Test
    public void 議事録を追加するとメールが送信される() throws NullPointerException,
            IllegalArgumentException, IOException, ServletException {
        // test@example.com というユーザがログイン中、という状態を作っておく。
        TestEnvironment environment =
            (TestEnvironment) ApiProxy.getCurrentEnvironment();
        environment.setEmail("test@example.com");
        // メール送信API をフックするApiProxy.Delegate を適用しておく。
        @SuppressWarnings("rawtypes")
        Delegate parentDelegate = ApiProxy.getDelegate();
        MailDelegate mailDelegate = new MailDelegate();
        ApiProxy.setDelegate(mailDelegate);
        tester.request.setMethod("POST");
        tester.param("title", " テスト用議事録1");
        tester.start(PATH);
        assertThat(" メールが送信される", mailDelegate.messages.size(), is(1));
        MailMessage mail = mailDelegate.messages.get(0);
        assertThat(
            "From",
            mail.getSender(),
            is("minutes@yourappid.appspotmail.com"));
        assertThat("Subject", mail.getSubject(), is(" 新しい議事録が追加されました"));
        assertThat(
            "Body",
            mail.getTextBody(Charset.forName("utf-8")),
            containsString("http://localhost/minutes.html?minutes="));
        // ApiProxy.Delegate をもとに戻す。
        ApiProxy.setDelegate(parentDelegate);
    }

    @Test
    public void 議事録の削除要求を受け付ける_ログインしていない() throws NullPointerException,
            IllegalArgumentException, IOException, ServletException {
        Key minutesKey = MinutesService.put(" テスト用議事録");
        for (int i = 0; i < 5; i++) {
            MemoService.put(minutesKey, "memo" + i);
        }
        tester.param("delete", Datastore.keyToString(minutesKey));
        tester.start(PATH);
        assertThat(
            "MinutesController のインスタンスが使用される",
            tester.getController(),
            instanceOf(MinutesController.class));
        assertThat(
            " レスポンスコードが401",
            tester.response.getStatus(),
            is(HttpServletResponse.SC_UNAUTHORIZED));
    }

    @Test
    public void 議事録の削除要求を受け付ける_議事録作成者以外が要求する() throws NullPointerException,
            IllegalArgumentException, IOException, ServletException {
        // test@example.com というユーザがログイン中、という状態を作っておく。
        TestEnvironment environment =
            (TestEnvironment) ApiProxy.getCurrentEnvironment();
        environment.setEmail("test@example.com");
        Key minutesKey = MinutesService.put(" テスト用議事録");
        for (int i = 0; i < 5; i++) {
            MemoService.put(minutesKey, "memo" + i);
        }
        // 作成者以外がログインした状態にする
        environment.setEmail("other@example.com");
        tester.param("delete", Datastore.keyToString(minutesKey));
        tester.start(PATH);
        assertThat(
            "MinutesController のインスタンスが使用される",
            tester.getController(),
            instanceOf(MinutesController.class));
        assertThat(
            " レスポンスコードが403",
            tester.response.getStatus(),
            is(HttpServletResponse.SC_FORBIDDEN));
    }

    @Test
    public void 議事録の削除要求を受け付ける() throws NullPointerException,
            IllegalArgumentException, IOException, ServletException {
        // test@example.com というユーザがログイン中、という状態を作っておく。
        TestEnvironment environment =
            (TestEnvironment) ApiProxy.getCurrentEnvironment();
        environment.setEmail("test@example.com");
        Key minutesKey = MinutesService.put(" テスト用議事録");
        for (int i = 0; i < 5; i++) {
            MemoService.put(minutesKey, "memo" + i);
        }
        Minutes minutes = Datastore.get(Minutes.class, minutesKey);
        // メール送信API をフックするApiProxy.Delegate を適用しておく。
        @SuppressWarnings("rawtypes")
        Delegate parentDelegate = ApiProxy.getDelegate();
        MailDelegate mailDelegate = new MailDelegate();
        ApiProxy.setDelegate(mailDelegate);
        tester.param("delete", Datastore.keyToString(minutesKey));
        tester.start(PATH);
        assertThat(
            "MinutesController のインスタンスが使用される",
            tester.getController(),
            instanceOf(MinutesController.class));
        assertThat(
            " レスポンスコードが204",
            tester.response.getStatus(),
            is(HttpServletResponse.SC_NO_CONTENT));
        assertThat(" メールが送信される", mailDelegate.messages.size(), is(1));
        MailMessage mail = mailDelegate.messages.get(0);
        assertThat(
            "From",
            mail.getSender(),
            is("minutes@yourappid.appspotmail.com"));
        assertThat("To", mail.getTo(0), is("test@example.com"));
        assertThat(
            "Subject",
            mail.getSubject(),
            is(" 議事録[" + minutes.getTitle() + "] がTSV に変換されました"));
        assertThat(
            "Body",
            mail.getTextBody(Charset.forName("utf-8")),
            containsString("http://localhost/minutes?download="));
        // ApiProxy.Delegate をもとに戻す。
        ApiProxy.setDelegate(parentDelegate);
    }

    static class MailDelegate implements Delegate<Environment> {
        @SuppressWarnings("unchecked")
        final Delegate<Environment> parent = ApiProxy.getDelegate();

        public void flushLogs(Environment environment) {
            parent.flushLogs(environment);
        }

        public List<Thread> getRequestThreads(Environment environment) {
            return parent.getRequestThreads(environment);
        }

        public void log(Environment environment, LogRecord record) {
            parent.log(environment, record);
        }

        public Future<byte[]> makeAsyncCall(Environment environment,
                String packageName, String methodName, byte[] request,
                ApiConfig apiConfig) {
            inspectMailService(packageName, methodName, request);
            return parent.makeAsyncCall(
                environment,
                packageName,
                methodName,
                request,
                apiConfig);
        }

        public byte[] makeSyncCall(Environment environment, String packageName,
                String methodName, byte[] request) throws ApiProxyException {
            inspectMailService(packageName, methodName, request);
            return parent.makeSyncCall(
                environment,
                packageName,
                methodName,
                request);
        }

        final List<MailMessage> messages = new ArrayList<MailMessage>();

        void inspectMailService(String packageName, String methodName,
                byte[] request) {
            if (packageName.equals("mail")
                && (methodName.equals("SendToAdmins") || methodName
                    .equals("Send"))) {
                // mail#SendToAdmins RPC が実行された場合
                // バイト配列からProtocolBuffer オブジェクトを組立て直し、messages に追加する。
                MailMessage messagePb = new MailMessage();
                messagePb.mergeFrom(request);
                messages.add(messagePb);
            }
        }
    }
}
TOP

Related Classes of gaej2011.controller.MinutesControllerTest$MailDelegate

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.