<commit_before>// Copyright 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.google.sps;

import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.powermock.api.mockito.PowerMockito.mockStatic;

import com.google.appengine.api.blobstore.BlobInfo;
import com.google.appengine.api.blobstore.BlobInfoFactory;
import com.google.appengine.api.blobstore.BlobKey;
import com.google.appengine.api.blobstore.BlobstoreService;
import com.google.appengine.api.blobstore.UploadOptions;
import com.google.appengine.api.blobstore.UploadOptions.Builder;
import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.FetchOptions;
import com.google.appengine.api.datastore.PreparedQuery;
import com.google.appengine.api.datastore.Query;
import com.google.appengine.api.datastore.Text;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;
import com.google.appengine.tools.development.testing.LocalDatastoreServiceTestConfig;
import com.google.appengine.tools.development.testing.LocalServiceTestHelper;
import com.google.appengine.tools.development.testing.LocalUserServiceTestConfig;
import com.google.common.collect.ImmutableMap;
import com.google.gson.Gson;
import com.google.sps.data.AnalysisResults;
import com.google.sps.servlets.ReceiptAnalysis;
import com.google.sps.servlets.ReceiptAnalysis.ReceiptAnalysisException;
import com.google.sps.servlets.UploadReceiptServlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.URL;
import java.time.Clock;
import java.time.Instant;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

@RunWith(PowerMockRunner.class)
@PrepareForTest(ReceiptAnalysis.class)
public final class UploadReceiptServletTest {
  private static final String FILE_NOT_SELECTED_LIVE_SERVER_WARNING =
      "com.google.sps.servlets.UploadReceiptServlet$FileNotSelectedException: No file was uploaded by the user (live server).";
  private static final String FILE_NOT_SELECTED_DEV_SERVER_WARNING =
      "com.google.sps.servlets.UploadReceiptServlet$FileNotSelectedException: No file was uploaded by the user (dev server).";
  private static final String INVALID_FILE_WARNING =
      "com.google.sps.servlets.UploadReceiptServlet$InvalidFileException: Uploaded file must be a JPEG image.";
  private static final String USER_NOT_LOGGED_IN_WARNING =
      "com.google.sps.servlets.UploadReceiptServlet$UserNotLoggedInException: User must be logged in to upload a receipt.";
  private static final String INVALID_DATE_RANGE_WARNING =
      "com.google.sps.servlets.UploadReceiptServlet$InvalidDateException: Transaction date must be in the past.";
  private static final String INVALID_DATE_FORMAT_WARNING =
      "com.google.sps.servlets.UploadReceiptServlet$InvalidDateException: Transaction date must be a long.";
  private static final String RECEIPT_ANALYSIS_FAILED_WARNING =
      "com.google.sps.servlets.ReceiptAnalysis$ReceiptAnalysisException: Receipt analysis failed.";

  private static final String INSTANT = "2020-06-22T10:15:30Z";
  private static final long PAST_TIMESTAMP =
      Instant.parse(INSTANT).minusMillis(1234).toEpochMilli();

  private static final long MAX_UPLOAD_SIZE_BYTES = 5 * 1024 * 1024;
  private static final String UPLOAD_URL = "/blobstore/upload-receipt";

  private static final BlobKey BLOB_KEY = new BlobKey("blobKey");
  private static final String VALID_FILENAME = "image.jpg";
  private static final String INVALID_FILENAME = "image.png";
  private static final String VALID_CONTENT_TYPE = "image/jpeg";
  private static final String INVALID_CONTENT_TYPE = "image/png";
  private static final long IMAGE_SIZE_1MB = 1024 * 1024;
  private static final long IMAGE_SIZE_0MB = 0;
  private static final String HASH = "35454B055CC325EA1AF2126E27707052";

  private static final String LABEL = "Label";
  private static final Text RAW_TEXT = new Text("raw text");
  private static final double PRICE = 5.89;
  private static final String STORE = "McDonald's";
  private static final String INVALID_DATE_TYPE = "2020-05-20";
  private static final AnalysisResults ANALYSIS_RESULTS = new AnalysisResults(RAW_TEXT.getValue());

  private static final String IMAGE_URL = "/serve-image?blob-key=" + BLOB_KEY.getKeyString();
  private static final String LIVE_SERVER_BASE_URL =
      "https://capstone-receipt-step-2020.uc.r.appspot.com:80";<commit_msg>Add categories to AnalysisResults constant<commit_after>// Copyright 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.google.sps;

import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.powermock.api.mockito.PowerMockito.mockStatic;

import com.google.appengine.api.blobstore.BlobInfo;
import com.google.appengine.api.blobstore.BlobInfoFactory;
import com.google.appengine.api.blobstore.BlobKey;
import com.google.appengine.api.blobstore.BlobstoreService;
import com.google.appengine.api.blobstore.UploadOptions;
import com.google.appengine.api.blobstore.UploadOptions.Builder;
import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.FetchOptions;
import com.google.appengine.api.datastore.PreparedQuery;
import com.google.appengine.api.datastore.Query;
import com.google.appengine.api.datastore.Text;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;
import com.google.appengine.tools.development.testing.LocalDatastoreServiceTestConfig;
import com.google.appengine.tools.development.testing.LocalServiceTestHelper;
import com.google.appengine.tools.development.testing.LocalUserServiceTestConfig;
import com.google.common.collect.ImmutableMap;
import com.google.gson.Gson;
import com.google.sps.data.AnalysisResults;
import com.google.sps.servlets.ReceiptAnalysis;
import com.google.sps.servlets.ReceiptAnalysis.ReceiptAnalysisException;
import com.google.sps.servlets.UploadReceiptServlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.URL;
import java.time.Clock;
import java.time.Instant;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Logger;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

@RunWith(PowerMockRunner.class)
@PrepareForTest(ReceiptAnalysis.class)
public final class UploadReceiptServletTest {
  private static final String FILE_NOT_SELECTED_LIVE_SERVER_WARNING =
      "com.google.sps.servlets.UploadReceiptServlet$FileNotSelectedException: No file was uploaded by the user (live server).";
  private static final String FILE_NOT_SELECTED_DEV_SERVER_WARNING =
      "com.google.sps.servlets.UploadReceiptServlet$FileNotSelectedException: No file was uploaded by the user (dev server).";
  private static final String INVALID_FILE_WARNING =
      "com.google.sps.servlets.UploadReceiptServlet$InvalidFileException: Uploaded file must be a JPEG image.";
  private static final String USER_NOT_LOGGED_IN_WARNING =
      "com.google.sps.servlets.UploadReceiptServlet$UserNotLoggedInException: User must be logged in to upload a receipt.";
  private static final String INVALID_DATE_RANGE_WARNING =
      "com.google.sps.servlets.UploadReceiptServlet$InvalidDateException: Transaction date must be in the past.";
  private static final String INVALID_DATE_FORMAT_WARNING =
      "com.google.sps.servlets.UploadReceiptServlet$InvalidDateException: Transaction date must be a long.";
  private static final String RECEIPT_ANALYSIS_FAILED_WARNING =
      "com.google.sps.servlets.ReceiptAnalysis$ReceiptAnalysisException: Receipt analysis failed.";

  private static final String INSTANT = "2020-06-22T10:15:30Z";
  private static final long PAST_TIMESTAMP =
      Instant.parse(INSTANT).minusMillis(1234).toEpochMilli();

  private static final long MAX_UPLOAD_SIZE_BYTES = 5 * 1024 * 1024;
  private static final String UPLOAD_URL = "/blobstore/upload-receipt";

  private static final BlobKey BLOB_KEY = new BlobKey("blobKey");
  private static final String VALID_FILENAME = "image.jpg";
  private static final String INVALID_FILENAME = "image.png";
  private static final String VALID_CONTENT_TYPE = "image/jpeg";
  private static final String INVALID_CONTENT_TYPE = "image/png";
  private static final long IMAGE_SIZE_1MB = 1024 * 1024;
  private static final long IMAGE_SIZE_0MB = 0;
  private static final String HASH = "35454B055CC325EA1AF2126E27707052";

  private static final String LABEL = "Label";
  private static final Text RAW_TEXT = new Text("raw text");
  private static final double PRICE = 5.89;
  private static final String STORE = "McDonald's";
  private static final String INVALID_DATE_TYPE = "2020-05-20";
  private static final Set<String> CATEGORIES = Collections.singleton("category");
  private static final AnalysisResults ANALYSIS_RESULTS =
      new AnalysisResults(RAW_TEXT.getValue(), CATEGORIES);

  private static final String IMAGE_URL = "/serve-image?blob-key=" + BLOB_KEY.getKeyString();
  private static final String LIVE_SERVER_BASE_URL =
      "https://capstone-receipt-step-2020.uc.r.appspot.com:80";
{'fraction_non_alphanumeric': 0.08998988877654196, 'fraction_numerical': 0.014998314796090328, 'mean_word_length': 5.514270032930845, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 4, 'https://': 4, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1550804', 'n_tokens_mistral': 3690, 'n_tokens_neox': 3521, 'n_words': 866}