Skip to content

Commit aa1aa4d

Browse files
committed
Additional Notes field under the recipe #228
Added notes field.
1 parent 2a07710 commit aa1aa4d

File tree

16 files changed

+392
-62
lines changed

16 files changed

+392
-62
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,244 @@
1+
{
2+
"formatVersion": 1,
3+
"database": {
4+
"version": 2,
5+
"identityHash": "01b8721f1ac5a34ff8cafe8c4f516546",
6+
"entities": [
7+
{
8+
"tableName": "recipes",
9+
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`recipeId` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `title` TEXT, `imageName` TEXT, `description` TEXT, `servings` TEXT, `preparationTime` TEXT, `source` TEXT, `ingredients` TEXT, `directions` TEXT, `notes` TEXT, `favorite` INTEGER NOT NULL)",
10+
"fields": [
11+
{
12+
"fieldPath": "recipeId",
13+
"columnName": "recipeId",
14+
"affinity": "INTEGER",
15+
"notNull": true
16+
},
17+
{
18+
"fieldPath": "title",
19+
"columnName": "title",
20+
"affinity": "TEXT",
21+
"notNull": false
22+
},
23+
{
24+
"fieldPath": "imageName",
25+
"columnName": "imageName",
26+
"affinity": "TEXT",
27+
"notNull": false
28+
},
29+
{
30+
"fieldPath": "description",
31+
"columnName": "description",
32+
"affinity": "TEXT",
33+
"notNull": false
34+
},
35+
{
36+
"fieldPath": "servings",
37+
"columnName": "servings",
38+
"affinity": "TEXT",
39+
"notNull": false
40+
},
41+
{
42+
"fieldPath": "preparationTime",
43+
"columnName": "preparationTime",
44+
"affinity": "TEXT",
45+
"notNull": false
46+
},
47+
{
48+
"fieldPath": "source",
49+
"columnName": "source",
50+
"affinity": "TEXT",
51+
"notNull": false
52+
},
53+
{
54+
"fieldPath": "ingredients",
55+
"columnName": "ingredients",
56+
"affinity": "TEXT",
57+
"notNull": false
58+
},
59+
{
60+
"fieldPath": "directions",
61+
"columnName": "directions",
62+
"affinity": "TEXT",
63+
"notNull": false
64+
},
65+
{
66+
"fieldPath": "notes",
67+
"columnName": "notes",
68+
"affinity": "TEXT",
69+
"notNull": false
70+
},
71+
{
72+
"fieldPath": "favorite",
73+
"columnName": "favorite",
74+
"affinity": "INTEGER",
75+
"notNull": true
76+
}
77+
],
78+
"primaryKey": {
79+
"autoGenerate": true,
80+
"columnNames": [
81+
"recipeId"
82+
]
83+
},
84+
"indices": [],
85+
"foreignKeys": []
86+
},
87+
{
88+
"tableName": "categories",
89+
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`categoryId` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT)",
90+
"fields": [
91+
{
92+
"fieldPath": "categoryId",
93+
"columnName": "categoryId",
94+
"affinity": "INTEGER",
95+
"notNull": true
96+
},
97+
{
98+
"fieldPath": "name",
99+
"columnName": "name",
100+
"affinity": "TEXT",
101+
"notNull": false
102+
}
103+
],
104+
"primaryKey": {
105+
"autoGenerate": true,
106+
"columnNames": [
107+
"categoryId"
108+
]
109+
},
110+
"indices": [],
111+
"foreignKeys": []
112+
},
113+
{
114+
"tableName": "recipes_with_categories",
115+
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`recipeId` INTEGER NOT NULL, `categoryId` INTEGER NOT NULL, PRIMARY KEY(`recipeId`, `categoryId`), FOREIGN KEY(`recipeId`) REFERENCES `recipes`(`recipeId`) ON UPDATE NO ACTION ON DELETE CASCADE , FOREIGN KEY(`categoryId`) REFERENCES `categories`(`categoryId`) ON UPDATE NO ACTION ON DELETE CASCADE )",
116+
"fields": [
117+
{
118+
"fieldPath": "recipeId",
119+
"columnName": "recipeId",
120+
"affinity": "INTEGER",
121+
"notNull": true
122+
},
123+
{
124+
"fieldPath": "categoryId",
125+
"columnName": "categoryId",
126+
"affinity": "INTEGER",
127+
"notNull": true
128+
}
129+
],
130+
"primaryKey": {
131+
"autoGenerate": false,
132+
"columnNames": [
133+
"recipeId",
134+
"categoryId"
135+
]
136+
},
137+
"indices": [
138+
{
139+
"name": "index_recipes_with_categories_recipeId",
140+
"unique": false,
141+
"columnNames": [
142+
"recipeId"
143+
],
144+
"orders": [],
145+
"createSql": "CREATE INDEX IF NOT EXISTS `index_recipes_with_categories_recipeId` ON `${TABLE_NAME}` (`recipeId`)"
146+
},
147+
{
148+
"name": "index_recipes_with_categories_categoryId",
149+
"unique": false,
150+
"columnNames": [
151+
"categoryId"
152+
],
153+
"orders": [],
154+
"createSql": "CREATE INDEX IF NOT EXISTS `index_recipes_with_categories_categoryId` ON `${TABLE_NAME}` (`categoryId`)"
155+
}
156+
],
157+
"foreignKeys": [
158+
{
159+
"table": "recipes",
160+
"onDelete": "CASCADE",
161+
"onUpdate": "NO ACTION",
162+
"columns": [
163+
"recipeId"
164+
],
165+
"referencedColumns": [
166+
"recipeId"
167+
]
168+
},
169+
{
170+
"table": "categories",
171+
"onDelete": "CASCADE",
172+
"onUpdate": "NO ACTION",
173+
"columns": [
174+
"categoryId"
175+
],
176+
"referencedColumns": [
177+
"categoryId"
178+
]
179+
}
180+
]
181+
},
182+
{
183+
"ftsVersion": "FTS4",
184+
"ftsOptions": {
185+
"tokenizer": "unicode61",
186+
"tokenizerArgs": [
187+
"tokenchars=#"
188+
],
189+
"contentTable": "recipes",
190+
"languageIdColumnName": "",
191+
"matchInfo": "FTS4",
192+
"notIndexedColumns": [],
193+
"prefixSizes": [],
194+
"preferredOrder": "ASC"
195+
},
196+
"contentSyncTriggers": [
197+
"CREATE TRIGGER IF NOT EXISTS room_fts_content_sync_recipes_fts_BEFORE_UPDATE BEFORE UPDATE ON `recipes` BEGIN DELETE FROM `recipes_fts` WHERE `docid`=OLD.`rowid`; END",
198+
"CREATE TRIGGER IF NOT EXISTS room_fts_content_sync_recipes_fts_BEFORE_DELETE BEFORE DELETE ON `recipes` BEGIN DELETE FROM `recipes_fts` WHERE `docid`=OLD.`rowid`; END",
199+
"CREATE TRIGGER IF NOT EXISTS room_fts_content_sync_recipes_fts_AFTER_UPDATE AFTER UPDATE ON `recipes` BEGIN INSERT INTO `recipes_fts`(`docid`, `title`, `description`, `source`, `ingredients`) VALUES (NEW.`rowid`, NEW.`title`, NEW.`description`, NEW.`source`, NEW.`ingredients`); END",
200+
"CREATE TRIGGER IF NOT EXISTS room_fts_content_sync_recipes_fts_AFTER_INSERT AFTER INSERT ON `recipes` BEGIN INSERT INTO `recipes_fts`(`docid`, `title`, `description`, `source`, `ingredients`) VALUES (NEW.`rowid`, NEW.`title`, NEW.`description`, NEW.`source`, NEW.`ingredients`); END"
201+
],
202+
"tableName": "recipes_fts",
203+
"createSql": "CREATE VIRTUAL TABLE IF NOT EXISTS `${TABLE_NAME}` USING FTS4(`title` TEXT, `description` TEXT, `source` TEXT, `ingredients` TEXT, tokenize=unicode61 `tokenchars=#`, content=`recipes`)",
204+
"fields": [
205+
{
206+
"fieldPath": "title",
207+
"columnName": "title",
208+
"affinity": "TEXT",
209+
"notNull": false
210+
},
211+
{
212+
"fieldPath": "description",
213+
"columnName": "description",
214+
"affinity": "TEXT",
215+
"notNull": false
216+
},
217+
{
218+
"fieldPath": "source",
219+
"columnName": "source",
220+
"affinity": "TEXT",
221+
"notNull": false
222+
},
223+
{
224+
"fieldPath": "ingredients",
225+
"columnName": "ingredients",
226+
"affinity": "TEXT",
227+
"notNull": false
228+
}
229+
],
230+
"primaryKey": {
231+
"autoGenerate": false,
232+
"columnNames": []
233+
},
234+
"indices": [],
235+
"foreignKeys": []
236+
}
237+
],
238+
"views": [],
239+
"setupQueries": [
240+
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
241+
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '01b8721f1ac5a34ff8cafe8c4f516546')"
242+
]
243+
}
244+
}

app/src/androidTest/java/com/flauschcode/broccoli/recipe/CreateAndEditRecipeActivityTest.java

+4-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ public class CreateAndEditRecipeActivityTest {
8181

8282
private ActivityScenario<CreateAndEditRecipeActivity> scenario;
8383

84-
private ArgumentCaptor<Recipe> recipeCaptor = ArgumentCaptor.forClass(Recipe.class);
84+
private final ArgumentCaptor<Recipe> recipeCaptor = ArgumentCaptor.forClass(Recipe.class);
8585

8686
private static final Recipe LAUCHKUCHEN = RecipeTestUtil.createLauchkuchen();
8787
private static final Recipe LAUCHKUCHEN_SAVED = RecipeTestUtil.createdAlreadySavedLauchkuchen();
@@ -144,6 +144,7 @@ public void save_new_recipe() throws IOException {
144144
onView(withId(android.R.id.content)).perform(swipeUp()); // scrollTo() does not work for NestedScrollViews
145145
onView(withId(R.id.new_ingredients)).perform(closeSoftKeyboard(), typeText(LAUCHKUCHEN.getIngredients())); // it seems not to be possible to make Espresso type the enter key in a deterministic way
146146
onView(withId(R.id.new_directions)).perform(closeSoftKeyboard(), typeText(LAUCHKUCHEN.getDirections()));
147+
onView(withId(R.id.new_notes)).perform(closeSoftKeyboard(), typeText(LAUCHKUCHEN.getNotes()));
147148

148149
onView(withId(R.id.button_save_recipe)).perform(click()); // TODO find out why there sometimes is such a long wait
149150

@@ -157,6 +158,7 @@ public void save_new_recipe() throws IOException {
157158
assertThat(recipe.getPreparationTime(), is(LAUCHKUCHEN.getPreparationTime()));
158159
assertThat(recipe.getIngredients(), is(LAUCHKUCHEN.getIngredients()));
159160
assertThat(recipe.getDirections(), is(LAUCHKUCHEN.getDirections()));
161+
assertThat(recipe.getNotes(), is(LAUCHKUCHEN.getNotes()));
160162
assertThat(recipe.getImageName(), startsWith("12345.jpg"));
161163
assertThat(recipe.getCategories().size(), is(1));
162164
assertThat(recipe.getCategories().get(0), is(categoryHauptgerichte));
@@ -179,6 +181,7 @@ public void edit_recipe(){
179181
onView(withId(R.id.new_preparation_time)).check(matches(withText(LAUCHKUCHEN_SAVED.getPreparationTime())));
180182
onView(withId(R.id.new_ingredients)).check(matches(withText(LAUCHKUCHEN_SAVED.getIngredients())));
181183
onView(withId(R.id.new_directions)).check(matches(withText(LAUCHKUCHEN_SAVED.getDirections())));
184+
onView(withId(R.id.new_notes)).check(matches(withText(LAUCHKUCHEN_SAVED.getNotes())));
182185

183186
onView(withId(R.id.new_servings)).perform(replaceText("1 Portion"));
184187
onView(withId(R.id.button_save_recipe)).perform(click());

app/src/androidTest/java/com/flauschcode/broccoli/util/RecipeTestUtil.java

+2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ public static Recipe createLauchkuchen() {
1515
recipe.setPreparationTime("50 Minuten");
1616
recipe.setIngredients("500g Mehl\n2 Stangen Lauch");
1717
recipe.setDirections("1. Lauch schnippeln und Teig machen.\n2. Kochen und backen.");
18+
recipe.setNotes("Ein paar Anmerkungen zum Lauchkuchen.");
1819
recipe.getCategories().add(new Category("Hauptgerichte"));
1920
recipe.getCategories().add(new Category("Gebackenes"));
2021
return recipe;
@@ -39,6 +40,7 @@ public static Recipe createNusskuchen() {
3940
recipe.setPreparationTime("1 Stunde");
4041
recipe.setIngredients("500g Mehl\nviel Schokolade");
4142
recipe.setDirections("1. Teig machen.\n2. Backen.\n 3. Schokolade dazu.");
43+
recipe.setNotes("Ein paar Anmerkungen zum Nusskuchen.");
4244
return recipe;
4345
}
4446

Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
package com.flauschcode.broccoli;
22

3-
import android.content.Context;
4-
3+
import androidx.room.AutoMigration;
54
import androidx.room.Database;
6-
import androidx.room.Room;
75
import androidx.room.RoomDatabase;
86

97
import com.flauschcode.broccoli.category.Category;
@@ -13,20 +11,21 @@
1311
import com.flauschcode.broccoli.recipe.RecipeCategoryAssociation;
1412
import com.flauschcode.broccoli.recipe.RecipeDAO;
1513

16-
@Database(entities = {CoreRecipe.class, Category.class, RecipeCategoryAssociation.class, CoreRecipeFts.class}, version = 1)
14+
@Database(
15+
version = 2,
16+
entities = {
17+
CoreRecipe.class,
18+
Category.class,
19+
RecipeCategoryAssociation.class,
20+
CoreRecipeFts.class
21+
},
22+
autoMigrations = {
23+
@AutoMigration(from = 1, to = 2)
24+
}
25+
)
1726
public abstract class BroccoliDatabase extends RoomDatabase {
1827

19-
private static BroccoliDatabase broccoliDatabase;
20-
21-
public abstract RecipeDAO getRecipeDAO();
22-
public abstract CategoryDAO getCategoryDAO();
23-
24-
public static synchronized BroccoliDatabase get(Context context) {
25-
if (broccoliDatabase == null) {
26-
broccoliDatabase = Room.databaseBuilder(context.getApplicationContext(), BroccoliDatabase.class, "broccoli")
27-
.build();
28-
}
29-
return broccoliDatabase;
30-
}
28+
public abstract RecipeDAO recipeDAO();
29+
public abstract CategoryDAO categoryDAO();
3130

3231
}

app/src/main/java/com/flauschcode/broccoli/category/Category.java

+2-3
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,13 @@
55
import androidx.room.PrimaryKey;
66

77
import com.fasterxml.jackson.annotation.JsonIgnore;
8-
import com.flauschcode.broccoli.BroccoliApplication;
9-
10-
import com.flauschcode.broccoli.R;
8+
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
119

1210
import java.io.Serializable;
1311
import java.util.Objects;
1412

1513
@Entity(tableName = "categories")
14+
@JsonIgnoreProperties(ignoreUnknown = true)
1615
public class Category implements Serializable {
1716

1817
@PrimaryKey(autoGenerate = true)

0 commit comments

Comments
 (0)