package com.mydreamjob.application; import com.mydreamjob.config.MySql57MigrationConfiguration; import org.flywaydb.core.Flyway; import org.junit.jupiter.api.Test; import org.testcontainers.containers.MySQLContainer; import java.sql.*; import static org.junit.jupiter.api.Assertions.*; /** 真实 MySQL 5.7/8:V57 原数据升级、生成占位、唯一约束和旧关联保留。 */ class ApplicationReapplicationMigrationTest { @Test void mysql57Upgrade() throws Exception { verify("mysql:5.7.36"); } @Test void mysql8Upgrade() throws Exception { verify("mysql:8.4"); } Flyway flyway(String url,String user,String pass,String target) { var config=Flyway.configure().dataSource(url,user,pass).locations("classpath:db/migration"); if(target!=null) config.target(target); MySql57MigrationConfiguration.configure(config); return config.load(); } void verify(String image) throws Exception { try(var mysql=new MySQLContainer<>(image).withDatabaseName("qsp_reapply_migration") .withUsername("reapply").withPassword("isolated-only") .withCreateContainerCmdModifier(cmd->cmd.getHostConfig().withMemory(768L*1024*1024))) { mysql.start();String base=mysql.getJdbcUrl(); String url=base+(base.contains("?")?"&":"?")+"characterEncoding=UTF-8"; try(var c=DriverManager.getConnection(url,mysql.getUsername(),mysql.getPassword());var s=c.createStatement()) { s.execute("ALTER DATABASE qsp_reapply_migration CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci"); flyway(url,mysql.getUsername(),mysql.getPassword(),"57").migrate(); s.execute("INSERT INTO users(id,phone,role,is_active,is_verified) VALUES(990001,'19908000001','COMPANY',1,1),(990002,'19908000002','STUDENT',1,1)"); s.execute("INSERT INTO companies(id,owner_user_id,name,verified) VALUES(990001,990001,'synthetic migration',1)"); s.execute("INSERT INTO jobs(id,company_id,title,description,city,employment_type,status) VALUES(990001,990001,'synthetic','test','test','FULL_TIME','PUBLISHED'),(990002,990001,'blocked','test','test','FULL_TIME','PUBLISHED')"); s.execute("INSERT INTO applications(id,job_id,student_user_id,status) VALUES(990001,990001,990002,'WITHDRAWN'),(990002,990002,990002,'REJECTED')"); s.execute("INSERT INTO application_status_history(application_id,operator_user_id,from_status,to_status) VALUES(990001,990002,'SUBMITTED','WITHDRAWN')"); s.execute("INSERT INTO application_match_records(application_id,job_id,company_id,candidate_id,status) VALUES(990001,990001,990001,990002,'MATCHED')"); assertEquals(1,flyway(url,mysql.getUsername(),mysql.getPassword(),"58").migrate().migrationsExecuted); assertEquals("WITHDRAWN",scalar(s,"SELECT status FROM applications WHERE id=990001")); assertEquals("1",scalar(s,"SELECT attempt_number FROM applications WHERE id=990001")); assertNull(scalar(s,"SELECT active_application_key FROM applications WHERE id=990001")); assertEquals("1",scalar(s,"SELECT active_application_key FROM applications WHERE id=990002")); assertEquals("MATCHED",scalar(s,"SELECT status FROM application_match_records WHERE application_id=990001")); assertEquals("1",scalar(s,"SELECT COUNT(*) FROM application_status_history WHERE application_id=990001")); s.execute("INSERT INTO applications(id,job_id,student_user_id,status,attempt_number,previous_application_id) VALUES(990003,990001,990002,'SUBMITTED',2,990001)"); assertThrows(SQLException.class,()->s.execute("INSERT INTO applications(job_id,student_user_id,status,attempt_number) VALUES(990001,990002,'SUBMITTED',3)")); assertThrows(SQLException.class,()->s.execute("INSERT INTO applications(job_id,student_user_id,status,attempt_number) VALUES(990002,990002,'SUBMITTED',2)")); s.execute("UPDATE applications SET status='WITHDRAWN' WHERE id=990003"); s.execute("INSERT INTO applications(job_id,student_user_id,status,attempt_number,previous_application_id) VALUES(990001,990002,'SUBMITTED',3,990003)"); assertThrows(SQLException.class,()->s.execute("INSERT INTO applications(job_id,student_user_id,status,attempt_number) VALUES(990001,990002,'WITHDRAWN',2)")); assertEquals("3",scalar(s,"SELECT COUNT(*) FROM applications WHERE job_id=990001")); flyway(url,mysql.getUsername(),mysql.getPassword(),"58").validate(); assertEquals(0,flyway(url,mysql.getUsername(),mysql.getPassword(),"58").migrate().migrationsExecuted); } } } String scalar(Statement s,String sql) throws SQLException {try(var r=s.executeQuery(sql)){assertTrue(r.next());return r.getString(1);}} }