// Path: parser/src/main/java/me/vertretungsplan/objects/SubstitutionScheduleData.java
// public class SubstitutionScheduleData {
//     private SubstitutionSchedule.Type type;
//     private String api;
//     private List<String> additionalInfos;
//     private JSONObject data;
//     private AuthenticationData authenticationData;
// 
//     public SubstitutionScheduleData() {
//         additionalInfos = new ArrayList<>();
//     }
// 
//     /**
//      * Get the {@link SubstitutionSchedule.Type} of the substitution schedule this data represents
//      * @return the type of this schedule
//      */
//     public SubstitutionSchedule.Type getType() {
//         return type;
//     }
// 
//     /**
//      * Set the {@link SubstitutionSchedule.Type} of the substitution schedule this data represents
//      * @param type the type of this schedule
//      */
//     @SuppressWarnings("SameParameterValue")
//     public void setType(SubstitutionSchedule.Type type) {
//         this.type = type;
//     }
// 
//     /**
//      * Get the type of parser to use for this schedule, as a string representation. This is used by
//      * {@link me.vertretungsplan.parser.BaseParser#getInstance(SubstitutionScheduleData, CookieProvider)} to create a
//      * suitable parser instance.
//      *
//      * @return the type of parser to use
//      */
//     public String getApi() {
//         return api;
//     }
// 
//     /**
//      * Set the type of parser to use for this schedule, as a string representation. This information is used by
//      * {@link me.vertretungsplan.parser.BaseParser#getInstance(SubstitutionScheduleData, CookieProvider)} to create a
//      * suitable parser instance. Currently supported values are:
//      * <ul>
//      *     <li>{@code "untis-monitor"}</li>
//      *     <li>{@code "untis-info"}</li>
//      *     <li>{@code "untis-info-headless"}</li>
//      *     <li>{@code "untis-subst"}</li>
//      *     <li>{@code "dsbmobile"}</li>
//      *     <li>{@code "svplan"}</li>
//      *     <li>{@code "davinci"}</li>
//      *     <li>{@code "turbovertretung"}</li>
//      *     <li>{@code "csv"}</li>
//      *     <li>{@code "legionboard"}</li>
//      * </ul>
//      *
//      * @param api the type of parser to use
//      */
//     public void setApi(String api) {
//         this.api = api;
//     }
// 
//     /**
//      * Get the types of {@link AdditionalInfo} this schedule should contain. Used by
//      * {@link me.vertretungsplan.additionalinfo.BaseAdditionalInfoParser#getInstance(String)} to create a suitable
//      * parser instance.
//      *
//      * @return the set of additional info types
//      */
//     public List<String> getAdditionalInfos() {
//         return additionalInfos;
//     }
// 
//     /**
//      * Set the types of {@link AdditionalInfo} this schedule should contain. Used by
//      * {@link me.vertretungsplan.additionalinfo.BaseAdditionalInfoParser#getInstance(String)} to create a suitable
//      * parser instance. Currently supported values are:
//      * <ul>
//      *     <li>{@code "winter-sh"}</li>
//      * </ul>
//      *
//      * @param additionalInfos the additional info types to set
//      */
//     public void setAdditionalInfos(List<String> additionalInfos) {
//         this.additionalInfos = additionalInfos;
//     }
// 
//     /**
//      * Get additional data about this substitution schedule in form of a JSON object. What data is needed here
//      * depends on the parser type, see their own documentation in the <code>me.vertretungsplan.parser</code> package.
//      *
//      * @return additional data about this substitution schedule
//      */
//     public JSONObject getData() {
//         return data;
//     }
// 
//     /**
//      * Set additional data about this substitution schedule in form of a JSON object. What data is needed here
//      * depends on the parser type, see their own documentation in the <code>me.vertretungsplan.parser</code> package.
//      *
//      * @param data additional data about this substitution schedule
//      */
//     public void setData(JSONObject data) {
//         this.data = data;
//     }
// 
//     /**
//      * Get information about what kind of {@link me.vertretungsplan.objects.credential.Credential} is needed to parse
//      * this schedule and if there are additional parameters for authentication (such as a pre-set school number with
//      * only the password needing to be filled in). If no credential is needed, this should return a
//      * {@link me.vertretungsplan.objects.authentication.NoAuthenticationData} instance.
//      *
//      * @return the authentication data
//      */
//     public AuthenticationData getAuthenticationData() {
//         return authenticationData;
//     }
// 
//     /**
//      * Set information about what kind of {@link me.vertretungsplan.objects.credential.Credential} is needed to parse
//      * this schedule and if there are additional parameters for authentication (such as a pre-set school number with
//      * only the password needing to be filled in). If no credential is needed, set this to a
//      * {@link me.vertretungsplan.objects.authentication.NoAuthenticationData} instance.
//      *
//      * @param authenticationData the authentication data to set
//      */
//     public void setAuthenticationData(AuthenticationData authenticationData) {
//         this.authenticationData = authenticationData;
//     }
// }


import com.github.tomakehurst.wiremock.core.Options;
import com.github.tomakehurst.wiremock.junit.WireMockRule;
import me.vertretungsplan.exception.CredentialInvalidException;
import me.vertretungsplan.objects.SubstitutionScheduleData;
import me.vertretungsplan.objects.credential.UserPasswordCredential;
import org.apache.http.client.fluent.Executor;
import org.apache.http.client.fluent.Request;
import org.apache.http.impl.client.HttpClientBuilder;
import org.jetbrains.annotations.NotNull;
import org.json.JSONException;
import org.json.JSONObject;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import java.io.IOException;
import static com.github.tomakehurst.wiremock.client.WireMock.*;
import static org.junit.Assert.assertEquals;
package me.vertretungsplan.parser;




public class LoginHandlerTest {
    @Rule
    public WireMockRule wireMockRule = new WireMockRule(Options.DYNAMIC_PORT);

// Path: parser/src/main/java/me/vertretungsplan/objects/SubstitutionScheduleData.java
// public class SubstitutionScheduleData {
//     private SubstitutionSchedule.Type type;
//     private String api;
//     private List<String> additionalInfos;
//     private JSONObject data;
//     private AuthenticationData authenticationData;
// 
//     public SubstitutionScheduleData() {
//         additionalInfos = new ArrayList<>();
//     }
// 
//     /**
//      * Get the {@link SubstitutionSchedule.Type} of the substitution schedule this data represents
//      * @return the type of this schedule
//      */
//     public SubstitutionSchedule.Type getType() {
//         return type;
//     }
// 
//     /**
//      * Set the {@link SubstitutionSchedule.Type} of the substitution schedule this data represents
//      * @param type the type of this schedule
//      */
//     @SuppressWarnings("SameParameterValue")
//     public void setType(SubstitutionSchedule.Type type) {
//         this.type = type;
//     }
// 
//     /**
//      * Get the type of parser to use for this schedule, as a string representation. This is used by
//      * {@link me.vertretungsplan.parser.BaseParser#getInstance(SubstitutionScheduleData, CookieProvider)} to create a
//      * suitable parser instance.
//      *
//      * @return the type of parser to use
//      */
//     public String getApi() {
//         return api;
//     }
// 
//     /**
//      * Set the type of parser to use for this schedule, as a string representation. This information is used by
//      * {@link me.vertretungsplan.parser.BaseParser#getInstance(SubstitutionScheduleData, CookieProvider)} to create a
//      * suitable parser instance. Currently supported values are:
//      * <ul>
//      *     <li>{@code "untis-monitor"}</li>
//      *     <li>{@code "untis-info"}</li>
//      *     <li>{@code "untis-info-headless"}</li>
//      *     <li>{@code "untis-subst"}</li>
//      *     <li>{@code "dsbmobile"}</li>
//      *     <li>{@code "svplan"}</li>
//      *     <li>{@code "davinci"}</li>
//      *     <li>{@code "turbovertretung"}</li>
//      *     <li>{@code "csv"}</li>
//      *     <li>{@code "legionboard"}</li>
//      * </ul>
//      *
//      * @param api the type of parser to use
//      */
//     public void setApi(String api) {
//         this.api = api;
//     }
// 
//     /**
//      * Get the types of {@link AdditionalInfo} this schedule should contain. Used by
//      * {@link me.vertretungsplan.additionalinfo.BaseAdditionalInfoParser#getInstance(String)} to create a suitable
//      * parser instance.
//      *
//      * @return the set of additional info types
//      */
//     public List<String> getAdditionalInfos() {
//         return additionalInfos;
//     }
// 
//     /**
//      * Set the types of {@link AdditionalInfo} this schedule should contain. Used by
//      * {@link me.vertretungsplan.additionalinfo.BaseAdditionalInfoParser#getInstance(String)} to create a suitable
//      * parser instance. Currently supported values are:
//      * <ul>
//      *     <li>{@code "winter-sh"}</li>
//      * </ul>
//      *
//      * @param additionalInfos the additional info types to set
//      */
//     public void setAdditionalInfos(List<String> additionalInfos) {
//         this.additionalInfos = additionalInfos;
//     }
// 
//     /**
//      * Get additional data about this substitution schedule in form of a JSON object. What data is needed here
//      * depends on the parser type, see their own documentation in the <code>me.vertretungsplan.parser</code> package.
//      *
//      * @return additional data about this substitution schedule
//      */
//     public JSONObject getData() {
//         return data;
//     }
// 
//     /**
//      * Set additional data about this substitution schedule in form of a JSON object. What data is needed here
//      * depends on the parser type, see their own documentation in the <code>me.vertretungsplan.parser</code> package.
//      *
//      * @param data additional data about this substitution schedule
//      */
//     public void setData(JSONObject data) {
//         this.data = data;
//     }
// 
//     /**
//      * Get information about what kind of {@link me.vertretungsplan.objects.credential.Credential} is needed to parse
//      * this schedule and if there are additional parameters for authentication (such as a pre-set school number with
//      * only the password needing to be filled in). If no credential is needed, this should return a
//      * {@link me.vertretungsplan.objects.authentication.NoAuthenticationData} instance.
//      *
//      * @return the authentication data
//      */
//     public AuthenticationData getAuthenticationData() {
//         return authenticationData;
//     }
// 
//     /**
//      * Set information about what kind of {@link me.vertretungsplan.objects.credential.Credential} is needed to parse
//      * this schedule and if there are additional parameters for authentication (such as a pre-set school number with
//      * only the password needing to be filled in). If no credential is needed, set this to a
//      * {@link me.vertretungsplan.objects.authentication.NoAuthenticationData} instance.
//      *
//      * @param authenticationData the authentication data to set
//      */
//     public void setAuthenticationData(AuthenticationData authenticationData) {
//         this.authenticationData = authenticationData;
//     }
// }


// Path: parser/src/test/java/me/vertretungsplan/parser/LoginHandlerTest.java
import com.github.tomakehurst.wiremock.core.Options;
import com.github.tomakehurst.wiremock.junit.WireMockRule;
import me.vertretungsplan.exception.CredentialInvalidException;
import me.vertretungsplan.objects.SubstitutionScheduleData;
import me.vertretungsplan.objects.credential.UserPasswordCredential;
import org.apache.http.client.fluent.Executor;
import org.apache.http.client.fluent.Request;
import org.apache.http.impl.client.HttpClientBuilder;
import org.jetbrains.annotations.NotNull;
import org.json.JSONException;
import org.json.JSONObject;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import java.io.IOException;
import static com.github.tomakehurst.wiremock.client.WireMock.*;
import static org.junit.Assert.assertEquals;

package me.vertretungsplan.parser;




public class LoginHandlerTest {
    @Rule
    public WireMockRule wireMockRule = new WireMockRule(Options.DYNAMIC_PORT);

    private SubstitutionScheduleData dataBasic;