001package io.ebean.test; 002 003import io.ebean.DB; 004 005import java.io.IOException; 006import java.io.InputStream; 007 008import static org.assertj.core.api.Assertions.assertThat; 009 010/** 011 * Helper for testing to assert that the JSON form of an entity 012 * or list of entities match a String / typically test resource. 013 * 014 * <pre>{@code 015 * 016 * DbJson.of(timedEntries) 017 * .replace("id", "eventTime") 018 * .assertContentMatches("/assertJson/full-1-timed.json"); 019 * 020 * }</pre> 021 */ 022public class DbJson { 023 024 /** 025 * Create a PrettyJson object that has the JSON form of the 026 * entity bean or beans. 027 * 028 * <pre>{@code 029 * 030 * DbJson.of(timedEntries) 031 * .replace("id", "eventTime") 032 * .assertContentMatches("/assertJson/full-1-timed.json"); 033 * 034 * }</pre> 035 */ 036 public static PrettyJson of(Object bean) { 037 return new PrettyJson(DB.json().toJsonPretty(bean)); 038 } 039 040 /** 041 * Read the content for the given resource path. 042 */ 043 public static String readResource(String resourcePath) { 044 InputStream is = DbJson.class.getResourceAsStream(resourcePath); 045 try { 046 return IOUtils.readUtf8(is).trim(); 047 } catch (IOException e) { 048 throw new IllegalArgumentException(e); 049 } 050 } 051 052 /** 053 * Contains the JSON of beans(s). 054 */ 055 public static class PrettyJson { 056 057 private String placeHolder = "\"*\""; 058 private String rawJson; 059 060 PrettyJson(String rawJson) { 061 this.rawJson = rawJson; 062 } 063 064 /** 065 * Set the placeHolder to use when replacing property values. 066 */ 067 public PrettyJson withPlaceholder(String placeHolder) { 068 this.placeHolder = placeHolder; 069 return this; 070 } 071 072 /** 073 * Replace the values of the given properties with a placeholder value. 074 * <p> 075 * Typically we do this on generated properties such as id and timestamp properties. 076 * </p> 077 */ 078 public PrettyJson replace(String... propertyNames) { 079 for (String propertyName : propertyNames) { 080 String placeholder = "\"" + propertyName + "\": " + placeHolder; 081 rawJson = rawJson.replaceAll("\"" + propertyName + "\": (\\d+)", placeholder); 082 rawJson = rawJson.replaceAll("\"" + propertyName + "\": \"(.*?)\"", placeholder); 083 } 084 return this; 085 } 086 087 /** 088 * Return the JSON content. 089 */ 090 public String asJson() { 091 return rawJson; 092 } 093 094 /** 095 * Assert the json matches the content at the given resource path. 096 * 097 * <pre>{@code 098 * 099 * DbJson.of(timedEntries) 100 * .replace("id", "eventTime") 101 * .assertContentMatches("/assertJson/full-1-timed.json"); 102 * 103 * }</pre> 104 */ 105 public void assertContentMatches(String resourcePath) { 106 assertThat(rawJson).isEqualTo(readResource(resourcePath)); 107 } 108 } 109}