### Question:
LevelProgress { public static JSONObject winLevel(JSONObject json) { LevelProgress progress = new LevelProgress(json); JSONObject clone = new JSONObject(json.toString()); progress.change(progress.current + 1, Math.max(progress.passed, progress.current)); if (progress.isValid()) { return progress.saveTo(clone); } else { return null; } } LevelProgress();  LevelProgress(MultiplayerType type);  LevelProgress(JSONObject json); static LevelProgress parse(String jsonString); JSONObject saveTo(JSONObject json); void change(int level, int passed); void change(int level); static JSONObject winLevel(JSONObject json); boolean isValid(); boolean canChange(int level); @Override String toString();  }### Answer:
@Test public void nextLevel_skip_currentWillBeMoreThanPassed() { json = new JSONObject("{'levelProgress':{'total':3,'current':2,'lastPassed':0}}"); try { LevelProgress.winLevel(json); fail(); } catch (IllegalArgumentException e) { assertEquals("Progress is invalid: {'current':2,'passed':0,'total':3,'valid':false}", e.getMessage()); } }
@Test public void nextLevel_ok_currentCanBeEqualsTotal() { json = new JSONObject("{'levelProgress':{'total':3,'current':2,'lastPassed':2}}"); json = LevelProgress.winLevel(json); assertJson("{'levelProgress':{'total':3,'current':3,'lastPassed':2}}"); }
@Test public void nextLevel_skip_currentMoreThanTotal() { json = new JSONObject("{'levelProgress':{'total':2,'current':2,'lastPassed':2}}"); json = LevelProgress.winLevel(json); assertEquals(null, json); }
@Test public void nextLevel_ok_dontChangeLastPassed() { json = new JSONObject("{'a':'data','levelProgress':{'total':4,'current':2,'lastPassed':3}}"); json = LevelProgress.winLevel(json); assertJson("{'a':'data','levelProgress':{'total':4,'current':3,'lastPassed':3}}"); json = LevelProgress.winLevel(json); assertJson("{'a':'data','levelProgress':{'total':4,'current':4,'lastPassed':3}}"); json = LevelProgress.winLevel(json); assertEquals(null, json); }
@Test public void nextLevel_ok_increaseLassPassedWithCurrent() { json = new JSONObject("{'a':'data','levelProgress':{'total':4,'current':0,'lastPassed':-1}}"); assertJson("{'a':'data','levelProgress':{'total':4,'current':0,'lastPassed':-1}}"); json = LevelProgress.winLevel(json); assertJson("{'a':'data','levelProgress':{'total':4,'current':1,'lastPassed':0}}"); json = LevelProgress.winLevel(json); assertJson("{'a':'data','levelProgress':{'total':4,'current':2,'lastPassed':1}}"); json = LevelProgress.winLevel(json); assertJson("{'a':'data','levelProgress':{'total':4,'current':3,'lastPassed':2}}"); json = LevelProgress.winLevel(json); assertJson("{'a':'data','levelProgress':{'total':4,'current':4,'lastPassed':3}}"); json = LevelProgress.winLevel(json); assertEquals(null, json); }